From 33a48754cadd9fe65868fadbbdc08a3a1085c2f2 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 24 Mar 2020 15:28:38 +0530 Subject: [PATCH 01/58] Initial commit of JavacardKeymaster with empty functions --- .../4.0/JavacardKeymaster4Device.cpp | 216 ++++++++++++++++++ ...hardware.keymaster@4.0-service.javacard.rc | 4 + ...ardware.keymaster@4.0-service.javacard.xml | 11 + HAL/keymaster/4.0/service.cpp | 36 +++ HAL/keymaster/Android.bp | 41 ++++ .../include/JavacardKeymaster4Device.h | 102 +++++++++ 6 files changed, 410 insertions(+) create mode 100644 HAL/keymaster/4.0/JavacardKeymaster4Device.cpp create mode 100644 HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc create mode 100644 HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml create mode 100644 HAL/keymaster/4.0/service.cpp create mode 100644 HAL/keymaster/Android.bp create mode 100644 HAL/keymaster/include/JavacardKeymaster4Device.h diff --git a/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp new file mode 100644 index 00000000..dc725156 --- /dev/null +++ b/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp @@ -0,0 +1,216 @@ +/* + ** + ** 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. + */ + +#define LOG_TAG "android.hardware.keymaster@4.0-impl.trusty" + +#include +#include +#include +#include + +/* TODO Remove below UNUSED */ +#define UNUSED(a) a=a + +namespace keymaster { +namespace V4_0 { + +JavacardKeymaster4Device::JavacardKeymaster4Device() { + // TODO +} + +JavacardKeymaster4Device::~JavacardKeymaster4Device() { +} + +// Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. +Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { + // TODO implement + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { + // TODO implement + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { + // TODO implement + size_t size = params.size(); + UNUSED(size); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { + // TODO implement + UNUSED(operationHandle); + size_t size = parametersToVerify.size(); + UNUSED(size); + uint64_t challenge = authToken.challenge; + UNUSED(challenge); + UNUSED(_hidl_cb); + return Void(); +} + +Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { + // TODO implement + size_t size = data.size(); + UNUSED(size); + return ::android::hardware::keymaster::V4_0::ErrorCode {}; +} + +Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) { + // TODO implement + UNUSED(_hidl_cb); + size_t size = keyParams.size(); + UNUSED(size); + return Void(); +} + +Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { + // TODO implement + size_t size = keyParams.size(); + size = keyData.size(); + UNUSED(size); + UNUSED(keyFormat); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { + // TODO implement + size_t size = wrappedKeyData.size(); + size = wrappingKeyBlob.size(); + size = maskingKey.size(); + size = unwrappingParams.size(); + UNUSED(size); + UNUSED(passwordSid); + UNUSED(biometricSid); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) { + // TODO implement + size_t size = keyBlob.size(); + size = clientId.size(); + size = appData.size(); + UNUSED(size); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { + // TODO implement + size_t size = clientId.size(); + size = keyBlob.size(); + size = appData.size(); + UNUSED(size); + UNUSED(keyFormat); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) { + // TODO implement + size_t size = attestParams.size(); + size = keyToAttest.size(); + UNUSED(size); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) { + // TODO implement + size_t size = keyBlobToUpgrade.size(); + size = upgradeParams.size(); + UNUSED(size); + UNUSED(_hidl_cb); + return Void(); +} + +Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { + // TODO implement + size_t size = keyBlob.size(); + UNUSED(size); + return ::android::hardware::keymaster::V4_0::ErrorCode {}; +} + +Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteAllKeys() { + // TODO implement + return ::android::hardware::keymaster::V4_0::ErrorCode {}; +} + +Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::destroyAttestationIds() { + // TODO implement + return ::android::hardware::keymaster::V4_0::ErrorCode {}; +} + +Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) { + // TODO implement + UNUSED(purpose); + size_t size = keyBlob.size(); + size = inParams.size(); + UNUSED(size); + uint64_t challenge = authToken.challenge; + UNUSED(challenge); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) { + // TODO implement + UNUSED(operationHandle); + size_t size = inParams.size(); + size = input.size(); + UNUSED(size); + uint64_t challange = verificationToken.challenge; + challange = authToken.challenge; + UNUSED(challange); + UNUSED(_hidl_cb); + return Void(); +} + +Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) { + // TODO implement + UNUSED(operationHandle); + size_t size = inParams.size(); + size = input.size(); + size = signature.size(); + uint64_t challange = authToken.challenge; + challange = verificationToken.challenge; + UNUSED(challange); + UNUSED(_hidl_cb); + return Void(); +} + +Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::abort(uint64_t operationHandle) { + // TODO implement + UNUSED(operationHandle); + return ::android::hardware::keymaster::V4_0::ErrorCode {}; +} + + +// Methods from ::android::hidl::base::V1_0::IBase follow. + +//IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) { + //return new JavacardKeymaster4Device(); +//} +// +} // namespace android::hardware::keymaster::implementation +} diff --git a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc b/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc new file mode 100644 index 00000000..af0342e9 --- /dev/null +++ b/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc @@ -0,0 +1,4 @@ +service vendor.keymaster-4-0 /vendor/bin/hw/android.hardware.keymaster@4.0-service.javacard + class early_hal + user nobody + group drmrpc diff --git a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml b/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml new file mode 100644 index 00000000..aa30707c --- /dev/null +++ b/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml @@ -0,0 +1,11 @@ + + + android.hardware.keymaster + hwbinder + 4.0 + + IKeymasterDevice + default + + + diff --git a/HAL/keymaster/4.0/service.cpp b/HAL/keymaster/4.0/service.cpp new file mode 100644 index 00000000..db7c9631 --- /dev/null +++ b/HAL/keymaster/4.0/service.cpp @@ -0,0 +1,36 @@ +/* +** +** Copyright 2018, 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 +#include +#include +#include + +int main() { + ::android::hardware::configureRpcThreadpool(1, true); + + auto keymaster = new ::keymaster::V4_0::JavacardKeymaster4Device(); + + auto status = keymaster->registerAsService(); + if (status != android::OK) { + LOG(FATAL) << "Could not register service for Keymaster 4.0 (" << status << ")"; + return -1; + } + + android::hardware::joinRpcThreadpool(); + return -1; // Should never get here. +} diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp new file mode 100644 index 00000000..8676aaa6 --- /dev/null +++ b/HAL/keymaster/Android.bp @@ -0,0 +1,41 @@ +// FIXME: your file license if you have one + +cc_binary { + // FIXME: this should only be -impl for a passthrough hal. + // In most cases, to convert this to a binderized implementation, you should: + // - change '-impl' to '-service' here and make it a cc_binary instead of a + // cc_library_shared. + // - add a *.rc file for this module. + // - delete HIDL_FETCH_I* functions. + // - call configureRpcThreadpool and registerAsService on the instance. + // You may also want to append '-impl/-service' with a specific identifier like + // '-vendor' or '-' etc to distinguish it. + // FIXME: this should be 'vendor: true' for modules that will eventually be + // on AOSP. + name: "android.hardware.keymaster@4.0-service.javacard", + defaults: ["hidl_defaults"], + relative_install_path: "hw", + vendor: true, + init_rc: ["4.0/android.hardware.keymaster@4.0-service.javacard.rc"], + srcs: [ + "4.0/service.cpp", + "4.0/JavacardKeymaster4Device.cpp", + ], + local_include_dirs: [ + "include", + ], + shared_libs: [ + "liblog", + "libcutils", + "libdl", + "libbase", + "libutils", + "libhardware", + "libhidlbase", + "libkeymaster_messages", + "libcn-cbor", + "android.hardware.keymaster@4.0", + ], + + vintf_fragments: ["4.0/android.hardware.keymaster@4.0-service.javacard.xml"], +} diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h new file mode 100644 index 00000000..50f32d52 --- /dev/null +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -0,0 +1,102 @@ +/* + ** + ** 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. + */ + +#ifndef keymaster_V4_0_JavacardKeymaster4Device_H_ +#define keymaster_V4_0_JavacardKeymaster4Device_H_ + +#include +#include + +namespace keymaster { + +namespace V4_0 { + +using ::android::sp; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; +using ::android::hardware::keymaster::V4_0::HardwareAuthToken; +using ::android::hardware::keymaster::V4_0::HmacSharingParameters; +using ::android::hardware::keymaster::V4_0::IKeymasterDevice; +using ::android::hardware::keymaster::V4_0::KeyCharacteristics; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::SecurityLevel; +using ::android::hardware::keymaster::V4_0::Tag; +using ::android::hardware::keymaster::V4_0::VerificationToken; + +class JavacardKeymaster4Device : public IKeymasterDevice { + public: + explicit JavacardKeymaster4Device(); + virtual ~JavacardKeymaster4Device(); + + Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; + Return getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override; + Return computeSharedHmac(const hidl_vec& params, + computeSharedHmac_cb) override; + Return verifyAuthorization(uint64_t challenge, + const hidl_vec& parametersToVerify, + const HardwareAuthToken& authToken, + verifyAuthorization_cb _hidl_cb) override; + 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 importWrappedKey(const hidl_vec& wrappedKeyData, + const hidl_vec& wrappingKeyBlob, + const hidl_vec& maskingKey, + const hidl_vec& unwrappingParams, + uint64_t passwordSid, uint64_t biometricSid, + importWrappedKey_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 destroyAttestationIds() override; + Return begin(KeyPurpose purpose, const hidl_vec& key, + const hidl_vec& inParams, const HardwareAuthToken& authToken, + begin_cb _hidl_cb) override; + Return update(uint64_t operationHandle, const hidl_vec& inParams, + const hidl_vec& input, const HardwareAuthToken& authToken, + const VerificationToken& verificationToken, update_cb _hidl_cb) override; + Return finish(uint64_t operationHandle, const hidl_vec& inParams, + const hidl_vec& input, const hidl_vec& signature, + const HardwareAuthToken& authToken, + const VerificationToken& verificationToken, finish_cb _hidl_cb) override; + Return abort(uint64_t operationHandle) override; + +}; + +} // namespace V4_0 +} // namespace keymaster + +#endif // keymaster_V4_0_JavacardKeymaster4Device_H_ From f72a75c3c57c168f09c06a4914b44f9b52808cad Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Thu, 26 Mar 2020 16:42:49 +0000 Subject: [PATCH 02/58] Updated getHardwareInfo API --- HAL/keymaster/4.0/JavacardKeymaster4Device.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp index dc725156..786481f9 100644 --- a/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp @@ -37,8 +37,7 @@ JavacardKeymaster4Device::~JavacardKeymaster4Device() { // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); + _hidl_cb(SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); return Void(); } From 5e28d93bed62630bdd8191d968dba77af6a99304 Mon Sep 17 00:00:00 2001 From: cpathak Date: Fri, 27 Mar 2020 17:07:20 -0700 Subject: [PATCH 03/58] Optimization changes - removed command related classes and combined them into KMKeymasterApplet class - removed context class as it is no longer needed. - changed the random number generation logic to use aes cbc with aes 128 bit key encryption as simulator does not support aes ecb and aes 256 bit key. - changed exception throwing to use ISOException.throwit() to use runtime environment's instance. --- .../keymaster/KMAbortOperationCmd.java | 36 -- .../javacard/keymaster/KMAbstractCmd.java | 83 ---- .../keymaster/KMAddRngEntropyCmd.java | 70 --- .../android/javacard/keymaster/KMArray.java | 5 +- .../javacard/keymaster/KMAttestKeyCmd.java | 36 -- .../keymaster/KMBeginOperationCmd.java | 36 -- .../android/javacard/keymaster/KMBoolTag.java | 3 +- .../javacard/keymaster/KMByteBlob.java | 13 +- .../android/javacard/keymaster/KMByteTag.java | 5 +- .../android/javacard/keymaster/KMCommand.java | 43 -- .../keymaster/KMComputeSharedHmacCmd.java | 36 -- .../android/javacard/keymaster/KMContext.java | 119 ----- .../android/javacard/keymaster/KMDecoder.java | 47 +- .../keymaster/KMDeleteAllKeysCmd.java | 36 -- .../javacard/keymaster/KMDeleteKeyCmd.java | 36 -- .../keymaster/KMDestroyAttestationIdsCmd.java | 36 -- .../android/javacard/keymaster/KMEncoder.java | 5 +- .../android/javacard/keymaster/KMEnum.java | 3 +- .../javacard/keymaster/KMEnumArrayTag.java | 7 +- .../android/javacard/keymaster/KMEnumTag.java | 14 +- .../javacard/keymaster/KMException.java | 9 +- .../javacard/keymaster/KMExportKeyCmd.java | 36 -- .../keymaster/KMFinishOperationCmd.java | 36 -- .../javacard/keymaster/KMGenerateKeyCmd.java | 36 -- .../javacard/keymaster/KMGetHWInfoCmd.java | 52 --- .../KMGetHmacSharingParametersCmd.java | 36 -- .../keymaster/KMGetKeyCharacteristicsCmd.java | 36 -- .../keymaster/KMHardwareAuthToken.java | 3 +- .../keymaster/KMHmacSharingParameters.java | 3 +- .../javacard/keymaster/KMImportKeyCmd.java | 35 -- .../keymaster/KMImportWrappedKeyCmd.java | 35 -- .../android/javacard/keymaster/KMInteger.java | 16 +- .../javacard/keymaster/KMIntegerArrayTag.java | 7 +- .../javacard/keymaster/KMIntegerTag.java | 3 +- .../keymaster/KMKeyCharacteristics.java | 3 +- .../javacard/keymaster/KMKeymasterApplet.java | 429 +++++++++++++----- .../javacard/keymaster/KMMessenger.java | 22 - .../javacard/keymaster/KMOperationState.java | 8 +- .../javacard/keymaster/KMProvisionCmd.java | 61 --- .../javacard/keymaster/KMRepository.java | 130 ++---- .../keymaster/KMUpdateOperationCmd.java | 36 -- .../javacard/keymaster/KMUpgradeKeyCmd.java | 36 -- .../android/javacard/keymaster/KMUtil.java | 45 +- .../keymaster/KMVerificationToken.java | 3 +- .../keymaster/KMVerifyAuthorizationCmd.java | 36 -- 45 files changed, 480 insertions(+), 1341 deletions(-) delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMAbortOperationCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMAbstractCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMAddRngEntropyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMAttestKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMBeginOperationCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMCommand.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMComputeSharedHmacCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMContext.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMDeleteAllKeysCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMDeleteKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMDestroyAttestationIdsCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMExportKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMFinishOperationCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMGenerateKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMGetHWInfoCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMGetHmacSharingParametersCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMGetKeyCharacteristicsCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMImportKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMImportWrappedKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMMessenger.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMProvisionCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMUpdateOperationCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMUpgradeKeyCmd.java delete mode 100644 Applet/Applet/src/com/android/javacard/keymaster/KMVerifyAuthorizationCmd.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMAbortOperationCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMAbortOperationCmd.java deleted file mode 100644 index ee3e052a..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMAbortOperationCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMAbortOperationCmd extends KMAbstractCmd { - public static final byte INS_ABORT_OPERATION_CMD = 0x22; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_ABORT_OPERATION_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMAbstractCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMAbstractCmd.java deleted file mode 100644 index 02fad435..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMAbstractCmd.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public abstract class KMAbstractCmd implements KMCommand { - - /** - * Implements the KMCommand interface. - * - * @param context provides information required to execute the command. - */ - @Override - public void execute(KMContext context) { - // Assert the command's operational state - if (!this.validateState(context.getKeymasterState())) { - throw new KMException(KMException.CMD_NOT_ACCEPTED_WRONG_STATE); - } - KMEncoder encoder = context.getRepository().getEncoder(); - KMDecoder decoder = context.getRepository().getDecoder(); - // Get getExpectedArgs if expected - KMArray args = null; - if (hasArguments()) { - // Deserialize the getExpectedArgs - KMArray argsProto = getExpectedArgs(); - args = decoder.decode(argsProto, context.getBuffer(), (short) 0, context.getBufferLength()); - } - // Pass control to concrete command subclass - KMArray resp = this.process(args, context); - context.setBufferLength((short)0); - // If there is resp then serialize and send - if (resp != null) { - // set outgoing buffer - short len = encoder.encode(resp, context.getBuffer(), (short) 0, (short)context.getBuffer().length); - context.setBufferLength(len); - } - } - - /** - * Get the getExpectedArgs prototype expression from the concrete subclass. - * - * @return KMArray of KMType objects which provides expression for the command's getExpectedArgs.. - */ - protected abstract KMArray getExpectedArgs(); - - /** - * Implemented by the subclass to execute the command specific functionality. - * - * @param args which are decoded from the the apdu. - * @param context within which the command should be executed. - * @return Null or response having the result of the command's execution. - */ - protected abstract KMArray process(KMArray args, KMContext context); - - /** - * Validate the state required by the command to execute. By default all the commands can execute - * in active state. - * - * @param state is the current state of the applet - * @return true if the state is valid for command's execution else false is returned. - */ - protected boolean validateState(byte state) { - return (KMKeymasterApplet.ACTIVE_STATE == state); - } - - @Override - public boolean hasArguments(){ - return true; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMAddRngEntropyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMAddRngEntropyCmd.java deleted file mode 100644 index cb431b8f..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMAddRngEntropyCmd.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -import javacard.framework.ISO7816; -import javacard.framework.JCSystem; -import javacard.framework.Util; - -// This command adds entropy into the current entropy pool as per hal specifications. -public class KMAddRngEntropyCmd extends KMAbstractCmd { - public static final byte INS_ADD_RNG_ENTROPY_CMD = 0x18; - public static final short MAX_SEED_SIZE = 2048; - - @Override - protected KMArray getExpectedArgs() { - return KMArray.instance((short) 1).add((short) 0, KMByteBlob.instance()); - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - KMByteBlob blob = (KMByteBlob) args.get((short) 0); - // maximum 2KiB of seed is allowed. - if (blob.length() > MAX_SEED_SIZE) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); - } - KMUtil.init(context.getRepository()); - // Get existing entropy pool. - byte[] entPool = context.getRepository().getEntropyPool(); - // Create new temporary pool. - byte[] heapRef = context.getRepository().getByteHeapRef(); - short poolStart = context.getRepository().newByteArray((short) entPool.length); - // Populate the new pool with the entropy which is derived from current entropy pool. - KMUtil.newRandomNumber(heapRef, poolStart, (short) entPool.length); - // Copy the entropy to the current pool - updates the entropy pool. - Util.arrayCopy(heapRef, poolStart, entPool, (short) 0, (short) entPool.length); - short index = 0; - short randIndex = 0; - // Mix (XOR) the seed received from the master in the entropy pool - 32 bytes (entPool.length). - // at a time. - while (index < blob.length()) { - entPool[randIndex] = (byte) (entPool[randIndex] ^ blob.get(index)); - randIndex++; - index++; - if (randIndex >= entPool.length) { - randIndex = 0; - } - } - // TODO return success error code. - return null; - } - - @Override - public byte getIns() { - return INS_ADD_RNG_ENTROPY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMArray.java b/Applet/Applet/src/com/android/javacard/keymaster/KMArray.java index 23b5afe6..d2eed688 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMArray.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMArray.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMArray extends KMType { private KMType[] vals; @@ -67,7 +68,7 @@ public KMArray withLength(short length) { public KMArray add(short index, KMType val) { if (index >= length) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } vals[(short) (startOff + index)] = val; return this; @@ -75,7 +76,7 @@ public KMArray add(short index, KMType val) { public KMType get(short index) { if (index >= length) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return vals[(short) (startOff + index)]; } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMAttestKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMAttestKeyCmd.java deleted file mode 100644 index 9d51e231..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMAttestKeyCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMAttestKeyCmd extends KMAbstractCmd { - public static final byte INS_ATTEST_KEY_CMD = 0x14; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_ATTEST_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMBeginOperationCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMBeginOperationCmd.java deleted file mode 100644 index 2ab55233..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMBeginOperationCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMBeginOperationCmd extends KMAbstractCmd { - public static final byte INS_BEGIN_OPERATION_CMD = 0x1F; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_BEGIN_OPERATION_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java index 6cf41894..2e088893 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMBoolTag extends KMTag { @@ -81,7 +82,7 @@ public byte getVal() { // create default assignBlob without any value public static KMBoolTag instance(short key) { if (!validateKey(key)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMBoolTag tag = repository.newBoolTag(); tag.key = key; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java b/Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java index fca5b947..54b0e9e4 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.Util; // Byte val represents contiguous memory buffer. @@ -48,7 +49,7 @@ public static KMByteBlob instance() { // copy the blob public static KMByteBlob instance(byte[] blob, short startOff, short length) { if ((length <= 0) || ((short)(startOff+length) > blob.length)) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMByteBlob inst = instance(length); Util.arrayCopyNonAtomic(blob, startOff, inst.val, inst.startOff, inst.length); @@ -58,7 +59,7 @@ public static KMByteBlob instance(byte[] blob, short startOff, short length) { // returns empty blob with given length public static KMByteBlob instance(short length) { if (length <= 0) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMByteBlob inst = instance(); inst.startOff = repository.newByteArray(length); @@ -83,20 +84,20 @@ public KMByteBlob withLength(short len) { public void add(short index, byte val) { if (index >= this.length) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (this.val == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } this.val[(short) (startOff + index)] = val; } public byte get(short index) { if (index >= this.length) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (this.val == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } return this.val[(short) (startOff + index)]; } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java index c415abbc..1569394c 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMByteTag extends KMTag { @@ -74,7 +75,7 @@ public static KMByteTag instance() { public static KMByteTag instance(short key) { if (!validateKey(key)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMByteTag tag = repository.newByteTag(); tag.key = key; @@ -93,7 +94,7 @@ public static void create(KMByteTag[] byteTagRefTable) { // create default assignBlob without any value public static KMByteTag instance(short key, KMByteBlob array) { if (!validateKey(key)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMByteTag tag = repository.newByteTag(); tag.key = key; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMCommand.java b/Applet/Applet/src/com/android/javacard/keymaster/KMCommand.java deleted file mode 100644 index 9e17dd58..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -import javacard.framework.APDU; - -/** This interface declares methods to be implemented by the command instances. */ -public interface KMCommand { - /** - * Execute this command within given context. If the command fails then it throws an exception - * - * @param context provides information required to execute the command. - */ - void execute(KMContext context); - - /** - * Return the instruction code associated with this command. The implementations will provide this - * code. - * - * @return instruction code which is related APDU INS. - */ - byte getIns(); - - /** - * Indicates whether command has arguments. - * @ return true if the command has arguments - */ - boolean hasArguments(); -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMComputeSharedHmacCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMComputeSharedHmacCmd.java deleted file mode 100644 index 5d2e0b46..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMComputeSharedHmacCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMComputeSharedHmacCmd extends KMAbstractCmd { - public static final byte INS_COMPUTE_SHARED_HMAC_CMD = 0x19; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_COMPUTE_SHARED_HMAC_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMContext.java b/Applet/Applet/src/com/android/javacard/keymaster/KMContext.java deleted file mode 100644 index 0d081f89..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMContext.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -/** - * This class provides data structure for information which is passed between the Keymaster Applet - * and the commands. It is created by applet and initialized for the process request. Applet sets - * repository, apdu and keymasterState. Command sets and uses incoming buffer information, outgoing - * buffer information and operation state (if command is an operation). - */ -public class KMContext { - private KMRepository repository; - private byte keymasterState; - private KMOperationState opState; - private byte[] buffer; - private short bufferLength; - /** - * Setter for the keymasterState. Set by the applet. - * - * @param keymasterState represents current applet state. - */ - public void setKeymasterState(byte keymasterState) { - this.keymasterState = keymasterState; - } - - /** - * Getter for keymasterState. Used by the commands. - * - * @return keymasterState represents current applets state. - */ - public byte getKeymasterState() { - return keymasterState; - } - - - /** - * Getter for buffer used for receiving or sending data to or from the master. Used by the - * messenger. - * - * @return buffer which is used to copying data to and from apdu's buffer. Start offset is always - * 0. - */ - public byte[] getBuffer() { - return buffer; - } - - /** - * Setter for buffer. Used by the repository. - * - * @param buffer which is used to copying data to and from apdu's buffer. - */ - public void setBuffer(byte[] buffer) { - this.buffer = buffer; - } - - /** - * Getter for buffer length. Used by the messenger and commands. - * - * @return buffer length. - */ - public short getBufferLength() { - return bufferLength; - } - - /** - * Setter for buffer length. Used by the messenger commands. - * - * @param length of buffer. - */ - public void setBufferLength(short length) { - this.bufferLength = length; - } - - /** - * Getter for repository instance. Used by commands. - * - * @return repository - */ - public KMRepository getRepository() { - return repository; - } - - /** - * Setter for the repository instance. Used by the applet. - * - * @param repository is repository of the KMType objects and other objects. - */ - public void setRepository(KMRepository repository) { - this.repository = repository; - } - - /** - * Getter for the OperationState for operation specific commands. Used by commands. - * - * @return Operation state associated with the command. - */ - public KMOperationState getOpState() { - return opState; - } - - /** Setter for the OperationState for operation specific commands. Used by commands. */ - public void setOpState(KMOperationState opState) { - this.opState = opState; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java index 4cedfcaf..a1c43aa3 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.Util; // TODO Clean and refactor the code. public class KMDecoder { @@ -67,7 +68,7 @@ private KMIntegerArrayTag decode(KMIntegerArrayTag exp) { readTagKey(exp.getTagType()); // the values are array of integers. if (!(exp.getValues().getType() instanceof KMInteger)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } return exp.instance(this.tagKey, decode(exp.getValues(), (KMInteger) exp.getValues().getType())); } @@ -90,10 +91,10 @@ private KMBoolTag decode(KMBoolTag exp) { // BOOL Tag is a leaf node and it must always have tiny encoded uint value = 1. // TODO check this out. if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } if ((byte) (buffer[startOff] & ADDITIONAL_MASK) != 0x01) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } incrementStartOff((short) 1); return exp.instance(tagKey); @@ -104,12 +105,12 @@ private KMEnumTag decode(KMEnumTag exp) { // Enum Tag value will always be integer with max 1 byte length. // TODO Check this out. if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } short len = (short) (buffer[startOff] & ADDITIONAL_MASK); byte enumVal = 0; if (len > UINT8_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (len < UINT8_LENGTH) { enumVal = (byte)(len & ADDITIONAL_MASK); @@ -126,12 +127,12 @@ private KMEnum decode(KMEnum exp) { // Enum value will always be integer with max 1 byte length. if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } short len = (short) (buffer[startOff] & ADDITIONAL_MASK); byte enumVal = 0; if (len > UINT8_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (len < UINT8_LENGTH) { enumVal = (byte)(len & ADDITIONAL_MASK); @@ -147,9 +148,12 @@ private KMEnum decode(KMEnum exp) { private KMInteger decode(KMInteger exp) { KMInteger inst; if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } short len = (short) (buffer[startOff] & ADDITIONAL_MASK); + if(len > UINT64_LENGTH){ + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + } incrementStartOff((short) 1); if (len < UINT8_LENGTH) { inst = exp.uint_8((byte)(len & ADDITIONAL_MASK)); @@ -162,11 +166,9 @@ private KMInteger decode(KMInteger exp) { } else if (len == UINT32_LENGTH) { inst = exp.instance(buffer, startOff, (short) 4); incrementStartOff((short) 4); - } else if (len == UINT64_LENGTH) { + } else { inst = exp.instance(buffer, startOff, (short) 8); incrementStartOff((short) 8); - } else { - throw new KMException(ISO7816.SW_WRONG_LENGTH); } return inst; } @@ -181,7 +183,7 @@ private KMByteBlob decode(KMByteBlob exp) { private KMArray decode(KMArray exp) { short payloadLength = readMajorTypeWithPayloadLength(ARRAY_TYPE); if (exp.length() != payloadLength) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMArray inst = exp.instance(payloadLength); short index = 0; @@ -260,7 +262,7 @@ private KMType decode(KMType exp) { } if (exp instanceof KMVector) { if (!((((KMVector) exp).getType()) instanceof KMInteger)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } return decode((KMVector) exp, (KMInteger) ((KMVector) exp).getType()); } @@ -300,16 +302,17 @@ private KMType decode(KMType exp) { if (exp instanceof KMHardwareAuthToken) { return decode((KMHardwareAuthToken) exp); } - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); + return null; } private short peekTagType() { if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } if ((short) (buffer[startOff] & ADDITIONAL_MASK) != UINT32_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return (short) ((Util.makeShort(buffer[(short) (startOff + 1)], buffer[(short) (startOff + 2)])) @@ -318,16 +321,16 @@ private short peekTagType() { private void readTagKey(short expectedTagType) { if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } if ((byte) (buffer[startOff] & ADDITIONAL_MASK) != UINT32_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } incrementStartOff((short) 1); this.tagType = readShort(); this.tagKey = readShort(); if (tagType != expectedTagType) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } @@ -336,11 +339,11 @@ private short readMajorTypeWithPayloadLength(short majorType) { short payloadLength = 0; byte val = readByte(); if ((short) (val & MAJOR_TYPE_MASK) != majorType) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } short lenType = (short) (val & ADDITIONAL_MASK); if (lenType > UINT16_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (lenType < UINT8_LENGTH) { payloadLength = lenType; @@ -367,7 +370,7 @@ private byte readByte() { private void incrementStartOff(short inc) { startOff += inc; if (startOff > this.length) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteAllKeysCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteAllKeysCmd.java deleted file mode 100644 index 5c476cd0..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteAllKeysCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMDeleteAllKeysCmd extends KMAbstractCmd { - public static final byte INS_DELETE_ALL_KEYS_CMD = 0x17; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_DELETE_ALL_KEYS_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteKeyCmd.java deleted file mode 100644 index ced6e7e4..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMDeleteKeyCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMDeleteKeyCmd extends KMAbstractCmd { - public static final byte INS_DELETE_KEY_CMD = 0x16; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_DELETE_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMDestroyAttestationIdsCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMDestroyAttestationIdsCmd.java deleted file mode 100644 index fa66ab1f..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMDestroyAttestationIdsCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMDestroyAttestationIdsCmd extends KMAbstractCmd { - public static final byte INS_DESTROY_ATT_IDS_CMD = 0x1A; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_DESTROY_ATT_IDS_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java index a231563b..ec736de4 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.Util; public class KMEncoder { @@ -124,7 +125,7 @@ private void encode(KMType exp){ encode((KMHardwareAuthToken) exp); return; } - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } private void encode(KMKeyParameters obj) { @@ -288,7 +289,7 @@ private void writeByte(byte val){ private void incrementStartOff(short inc){ startOff += inc; if (startOff >= this.length) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java b/Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java index 7dad1d27..441fd833 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMEnum extends KMType { private static short[] types = {HARDWARE_TYPE, KEY_FORMAT, KEY_DERIVATION_FUNCTION}; @@ -48,7 +49,7 @@ public static KMEnum instance() { public static KMEnum instance(short enumType, byte val) { KMEnum inst = repository.newEnum(); if (!validateEnum(enumType, val)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } inst.type = enumType; inst.val = val; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java index 9c76ce66..30c40bad 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMEnumArrayTag extends KMTag { @@ -84,7 +85,7 @@ public static KMEnumArrayTag instance(short key) { // check if key is valid. byte[] vals = getAllowedEnumValues(key); if (vals == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMEnumArrayTag tag = repository.newEnumArrayTag(); tag.key = key; @@ -124,7 +125,7 @@ public static KMEnumArrayTag instance(short key, KMByteBlob blob) { // validate key byte[] allowedVals = getAllowedEnumValues(key); if (allowedVals == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } short byteIndex = 0; while (byteIndex < blob.length()) { @@ -138,7 +139,7 @@ public static KMEnumArrayTag instance(short key, KMByteBlob blob) { enumIndex++; } if (!validValue) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } byteIndex++; } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java index 3cfa840e..9a641425 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMEnumTag extends KMTag { @@ -60,13 +61,12 @@ public static KMEnumTag instance() { } public static KMEnumTag instance(short key) { - if (validateEnum(key, NO_VALUE)) { - KMEnumTag tag = repository.newEnumTag(); - tag.key = key; - return tag; - } else { - throw new KMException(ISO7816.SW_DATA_INVALID); + if(!validateEnum(key, NO_VALUE)){ + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } + KMEnumTag tag = repository.newEnumTag(); + tag.key = key; + return tag; } public static void create(KMEnumTag[] enumTagRefTable) { @@ -124,7 +124,7 @@ public byte getValue() { // instantiate enum tag. public static KMEnumTag instance(short key, byte val) { if (!validateEnum(key, val)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMEnumTag tag = instance(key); tag.val = val; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMException.java b/Applet/Applet/src/com/android/javacard/keymaster/KMException.java index 3e357613..3a26b047 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMException.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMException.java @@ -16,14 +16,13 @@ package com.android.javacard.keymaster; -import javacard.framework.ISOException; - -public class KMException extends ISOException { +public class KMException { // The Applet is not in a correct state in order to execute the command. public static final short CMD_NOT_ACCEPTED_WRONG_STATE = (short) 0x6901; - public KMException(short i) { - super(i); + + public static boolean handle(short reason) { + return false; } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMExportKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMExportKeyCmd.java deleted file mode 100644 index 05d28ef6..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMExportKeyCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMExportKeyCmd extends KMAbstractCmd { - public static final byte INS_EXPORT_KEY_CMD = 0x13; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_EXPORT_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMFinishOperationCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMFinishOperationCmd.java deleted file mode 100644 index 0267e4fb..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMFinishOperationCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMFinishOperationCmd extends KMAbstractCmd { - public static final byte INS_FINISH_OPERATION_CMD = 0x21; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_FINISH_OPERATION_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMGenerateKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMGenerateKeyCmd.java deleted file mode 100644 index 0c2d69d1..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMGenerateKeyCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMGenerateKeyCmd extends KMAbstractCmd { - public static final byte INS_GENERATE_KEY_CMD = 0x10; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_GENERATE_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMGetHWInfoCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMGetHWInfoCmd.java deleted file mode 100644 index 3f6cb8f8..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMGetHWInfoCmd.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMGetHWInfoCmd extends KMAbstractCmd { - public static final byte INS_GET_HW_INFO_CMD = 0x1E; - public static final byte[] JavacardKeymasterDevice = { - 0x4A, 0x61, 0x76, 0x61, 0x63, 0x61, 0x72, 0x64, 0x4B, 0x65, 0x79, 0x6D, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - }; - public static final byte[] Google = {0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65}; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return KMArray.instance((short) 3) - .add((short) 0, KMEnum.instance(KMType.HARDWARE_TYPE, KMType.STRONGBOX)) - .add( - (short) 1, - KMByteBlob.instance( - JavacardKeymasterDevice, (short) 0, (short) JavacardKeymasterDevice.length)) - .add((short) 2, KMByteBlob.instance(Google, (short) 0, (short) Google.length)); - } - - @Override - public byte getIns() { - return INS_GET_HW_INFO_CMD; - } - - @Override - public boolean hasArguments() { - return false; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMGetHmacSharingParametersCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMGetHmacSharingParametersCmd.java deleted file mode 100644 index 19165531..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMGetHmacSharingParametersCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMGetHmacSharingParametersCmd extends KMAbstractCmd { - public static final byte INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_GET_HMAC_SHARING_PARAM_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMGetKeyCharacteristicsCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMGetKeyCharacteristicsCmd.java deleted file mode 100644 index 20fef22b..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMGetKeyCharacteristicsCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMGetKeyCharacteristicsCmd extends KMAbstractCmd { - public static final byte INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_GET_KEY_CHARACTERISTICS_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java b/Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java index ca3c2804..9c188c67 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMHardwareAuthToken extends KMType { public static final byte CHALLENGE = 0x00; @@ -56,7 +57,7 @@ public static KMHardwareAuthToken instance() { public static KMHardwareAuthToken instance(KMArray vals) { if (vals.length() != 6) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMHardwareAuthToken inst = repository.newHwAuthToken(); inst.vals = vals; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java b/Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java index ef08696b..a1fca4d1 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMHmacSharingParameters extends KMType { public static final byte SEED = 0x00; @@ -47,7 +48,7 @@ public static KMHmacSharingParameters instance() { public static KMHmacSharingParameters instance(KMArray vals) { if (vals.length() != 2) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMHmacSharingParameters inst = repository.newHmacSharingParameters(); inst.vals = vals; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMImportKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMImportKeyCmd.java deleted file mode 100644 index 6be0d0d7..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMImportKeyCmd.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMImportKeyCmd extends KMAbstractCmd { - public static final byte INS_IMPORT_KEY_CMD = 0x11; - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_IMPORT_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMImportWrappedKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMImportWrappedKeyCmd.java deleted file mode 100644 index e9896748..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMImportWrappedKeyCmd.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMImportWrappedKeyCmd extends KMAbstractCmd { - public static final byte INS_IMPORT_WRAPPED_KEY_CMD = 0x12; - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_IMPORT_WRAPPED_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java b/Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java index 19996d18..987a0858 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.Util; // Represents 8 bit, 16 bit, 32 bit and 64 bit integers @@ -99,34 +100,35 @@ public KMInteger setValue(byte[] val) { public short getShort() { if (val == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } else if (val.length != 4) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return Util.makeShort(val[2], val[3]); } public byte getByte() { if (val == null) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } else if (val.length != 4) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return val[3]; } // copy the integer value from bytes public static KMInteger instance(byte[] num, short srcOff, short length) { + if(length > 8){ + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + } if (length == 1) { return uint_8(num[srcOff]); } else if (length == 2) { return uint_16(Util.makeShort(num[srcOff], num[(short) (srcOff + 1)])); } else if (length == 4) { return uint_32(num, srcOff); - } else if (length == 8) { - return uint_64(num, srcOff); } else { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + return uint_64(num, srcOff); } } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java index 9c9258a2..df96e114 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMIntegerArrayTag extends KMTag { private static final short[] tags = {USER_SECURE_ID}; @@ -69,7 +70,7 @@ public KMIntegerArrayTag asUlongArray() { public static KMIntegerArrayTag instance(short key) { if (!validateKey(key)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMIntegerArrayTag tag = repository.newIntegerArrayTag(); tag.key = key; @@ -79,10 +80,10 @@ public static KMIntegerArrayTag instance(short key) { public static KMIntegerArrayTag instance(short key, KMVector val) { if (!(val.getType() instanceof KMInteger)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } if (!(validateKey(key))) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMIntegerArrayTag tag = repository.newIntegerArrayTag(); tag.key = key; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java b/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java index 00dbf256..d583f6b2 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; // Implements UINT, ULONG and DATE tags. public class KMIntegerTag extends KMTag { @@ -78,7 +79,7 @@ public static KMIntegerTag instance() { public static KMIntegerTag instance(short key) { if (!validateKey(key)) { - throw new KMException(ISO7816.SW_DATA_INVALID); + ISOException.throwIt(ISO7816.SW_DATA_INVALID); } KMIntegerTag tag = repository.newIntegerTag(); tag.key = key; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java b/Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java index a6b5c7fe..d4c1a9b5 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMKeyCharacteristics extends KMType { public static final byte SOFTWARE_ENFORCED = 0x00; @@ -47,7 +48,7 @@ public static KMKeyCharacteristics instance() { public static KMKeyCharacteristics instance(KMArray vals) { if (vals.length() != 2) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMKeyCharacteristics inst = repository.newKeyCharacteristics(); inst.vals = vals; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 83512f92..0ee85ff1 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -19,7 +19,10 @@ import javacard.framework.APDU; import javacard.framework.Applet; import javacard.framework.AppletEvent; +import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; +import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; import javacardx.apdu.ExtendedLength; @@ -32,29 +35,63 @@ // - remove this in future. public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLength { // Constants. - public static final short MAX_LENGTH = (short) 0x04ff; // TODO: make this value configurable. + private static final short MAX_LENGTH = (short) 0x1000; // TODO: make this value configurable. private static final byte CLA_ISO7816_NO_SM_NO_CHAN = (byte) 0x80; - private static final byte KM_HAL_VERSION = (byte) 0x41; + private static final short KM_HAL_VERSION = (short) 0x4000; // Possible states of the applet. - public static final byte ILLEGAL_STATE = 0x00; - public static final byte INSTALL_STATE = 0x01; - public static final byte FIRST_SELECT_STATE = 0x02; - public static final byte ACTIVE_STATE = 0x03; - public static final byte INACTIVE_STATE = 0x04; - public static final byte UNINSTALLED_STATE = 0x05; + private static final byte ILLEGAL_STATE = 0x00; + private static final byte INSTALL_STATE = 0x01; + private static final byte FIRST_SELECT_STATE = 0x02; + private static final byte ACTIVE_STATE = 0x03; + private static final byte INACTIVE_STATE = 0x04; + private static final byte UNINSTALLED_STATE = 0x05; + + // Commands + private static final byte INS_GENERATE_KEY_CMD = 0x10; + private static final byte INS_IMPORT_KEY_CMD = 0x11; + private static final byte INS_IMPORT_WRAPPED_KEY_CMD = 0x12; + private static final byte INS_EXPORT_KEY_CMD = 0x13; + private static final byte INS_ATTEST_KEY_CMD = 0x14; + private static final byte INS_UPGRADE_KEY_CMD = 0x15; + private static final byte INS_DELETE_KEY_CMD = 0x16; + private static final byte INS_DELETE_ALL_KEYS_CMD = 0x17; + private static final byte INS_ADD_RNG_ENTROPY_CMD = 0x18; + private static final byte INS_COMPUTE_SHARED_HMAC_CMD = 0x19; + private static final byte INS_DESTROY_ATT_IDS_CMD = 0x1A; + private static final byte INS_VERIFY_AUTHORIZATION_CMD = 0x1B; + private static final byte INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C; + private static final byte INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D; + private static final byte INS_GET_HW_INFO_CMD = 0x1E; + private static final byte INS_BEGIN_OPERATION_CMD = 0x1F; + private static final byte INS_UPDATE_OPERATION_CMD = 0x20; + private static final byte INS_FINISH_OPERATION_CMD = 0x21; + private static final byte INS_ABORT_OPERATION_CMD = 0x22; + private static final byte INS_PROVISION_CMD = 0x23; + + // GetHwInfo information + // TODO change this to just filling the buffer + private static final byte[] JavacardKeymasterDevice = { + 0x4A, 0x61, 0x76, 0x61, 0x63, 0x61, 0x72, 0x64, 0x4B, 0x65, 0x79, 0x6D, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + }; + private static final byte[] Google = {0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65}; + private static final short MAX_SEED_SIZE = 2048; // State of the applet. - private byte keymasterState = ILLEGAL_STATE; + private KMEncoder encoder; + private KMDecoder decoder; private KMRepository repository; + private byte keymasterState = ILLEGAL_STATE; + private byte[] buffer; - /** - * Registers this applet. - * - * @param repo reference to the repository which manages all the NVM objects. - */ - protected KMKeymasterApplet(KMRepository repo) { - repository = repo; + /** Registers this applet. */ + protected KMKeymasterApplet() { + keymasterState = KMKeymasterApplet.INSTALL_STATE; + repository = KMRepository.instance(); + KMUtil.init(); + encoder = new KMEncoder(); + decoder = new KMDecoder(); register(); } @@ -66,11 +103,7 @@ protected KMKeymasterApplet(KMRepository repo) { * @param bLength the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { - KMRepository repo = new KMRepository(); - // TODO: Read the configuration from the package and pass the data in initialize method. - repo.initialize(); - KMKeymasterApplet keymaster = new KMKeymasterApplet(repo); - keymaster.setKeymasterState(KMKeymasterApplet.INSTALL_STATE); + KMKeymasterApplet keymaster = new KMKeymasterApplet(); } /** @@ -80,11 +113,11 @@ public static void install(byte[] bArray, short bOffset, byte bLength) { */ @Override public boolean select() { - repository.onSelect(); - if (getKeymasterState() == KMKeymasterApplet.INSTALL_STATE) { - setKeymasterState(KMKeymasterApplet.FIRST_SELECT_STATE); - } else if (getKeymasterState() == KMKeymasterApplet.INACTIVE_STATE) { - setKeymasterState(KMKeymasterApplet.ACTIVE_STATE); + KMRepository.instance().onSelect(); + if (keymasterState == KMKeymasterApplet.INSTALL_STATE) { + keymasterState = KMKeymasterApplet.FIRST_SELECT_STATE; + } else if (keymasterState == KMKeymasterApplet.INACTIVE_STATE) { + keymasterState = KMKeymasterApplet.ACTIVE_STATE; } else { return false; } @@ -94,34 +127,36 @@ public boolean select() { /** De-selects this applet. */ @Override public void deselect() { - repository.onDeselect(); - if (getKeymasterState() == KMKeymasterApplet.ACTIVE_STATE) { - setKeymasterState(KMKeymasterApplet.INACTIVE_STATE); + KMRepository.instance().onDeselect(); + if (keymasterState == KMKeymasterApplet.ACTIVE_STATE) { + keymasterState = KMKeymasterApplet.INACTIVE_STATE; } } /** Uninstalls the applet after cleaning the repository. */ @Override public void uninstall() { - repository.onUninstall(); - if (getKeymasterState() != KMKeymasterApplet.UNINSTALLED_STATE) { - setKeymasterState(KMKeymasterApplet.UNINSTALLED_STATE); + KMRepository.instance().onUninstall(); + if (keymasterState != KMKeymasterApplet.UNINSTALLED_STATE) { + keymasterState = KMKeymasterApplet.UNINSTALLED_STATE; } } /** * Processes an incoming APDU and handles it using command objects. * - * @see APDU * @param apdu the incoming APDU */ @Override public void process(APDU apdu) { - repository.onProcess(); + KMRepository.instance().onProcess(); + if (buffer == null) { + buffer = JCSystem.makeTransientByteArray(MAX_LENGTH, JCSystem.CLEAR_ON_RESET); + } // Verify whether applet is in correct state. - if ((getKeymasterState() != KMKeymasterApplet.ACTIVE_STATE) - && (getKeymasterState() != KMKeymasterApplet.FIRST_SELECT_STATE)) { - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + if ((keymasterState != KMKeymasterApplet.ACTIVE_STATE) + && (keymasterState != KMKeymasterApplet.FIRST_SELECT_STATE)) { + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } // If this is select applet apdu which is selecting this applet then return if (apdu.isISOInterindustryCLA()) { @@ -129,105 +164,295 @@ public void process(APDU apdu) { return; } } - // Read the apdu header and buffer. - byte[] buffer = apdu.getBuffer(); - byte apduClass = buffer[ISO7816.OFFSET_CLA]; - byte apduIns = buffer[ISO7816.OFFSET_INS]; - byte halVersion = buffer[ISO7816.OFFSET_P1]; - byte apduP2 = buffer[ISO7816.OFFSET_P2]; - + byte[] apduBuffer = apdu.getBuffer(); + byte apduClass = apduBuffer[ISO7816.OFFSET_CLA]; + byte apduIns = apduBuffer[ISO7816.OFFSET_INS]; + short P1P2 = Util.getShort(apduBuffer, ISO7816.OFFSET_P1); // Validate APDU Header. if ((apduClass != CLA_ISO7816_NO_SM_NO_CHAN)) { - throw new KMException(ISO7816.SW_CLA_NOT_SUPPORTED); - } else if ((halVersion != KMKeymasterApplet.KM_HAL_VERSION) && (apduP2 != (byte) 0x00)) { - throw new KMException(ISO7816.SW_INCORRECT_P1P2); + ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); + } else if (P1P2 != KMKeymasterApplet.KM_HAL_VERSION) { + ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } - - // Process the APDU. - try { - // Get the command object for specific INS from the repository. - KMCommand command = repository.getCommand(apduIns); - // Get the empty context object from the repository. - KMContext context = repository.getContext(); - // Initialize context - context.setKeymasterState(getKeymasterState()); - context.setBuffer(repository.getBuffer()); - if(command.hasArguments()){ - receiveIncoming(context, apdu); + // Validate whether INS can be supported + if (!(apduIns >= INS_GENERATE_KEY_CMD && apduIns <= INS_PROVISION_CMD)) { + ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); + } + // Validate if INS is provision command if applet is in FIRST_SELECT_STATE. + if (keymasterState == KMKeymasterApplet.FIRST_SELECT_STATE) { + if (apduIns != INS_PROVISION_CMD) { + ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } - // Execute the command. If the execution fails then an exception is thrown. - command.execute(context); - - // context has data that needs to be sent - if(context.getBufferLength() >0 ){ - sendOutgoing(context, apdu); + } + // Process the apdu + try { + // Handle the command + handle(apduIns, apdu); + } catch (CardRuntimeException exception) { + if (!(KMException.handle(exception.getReason()))) { + CardRuntimeException.throwIt(exception.getReason()); } - - // Update the Keymaster state according to the context. - setKeymasterState(context.getKeymasterState()); - } catch (KMException exception) { - // TODO: error handling for command related error. - // TODO: This should result in ISOException or exception with keymaster specific error codes + } finally { + // Reset the buffer. + Util.arrayFillNonAtomic(buffer, (short) 0, MAX_LENGTH, (byte) 0); } } - /** - * Sends a response, may be extended response, as requested by the command. - * - * @param context of current command. - */ - public void sendOutgoing(KMContext context, APDU apdu) { - // Initialize source - short srcLength = context.getBufferLength(); + /** Sends a response, may be extended response, as requested by the command. */ + private void sendOutgoing(byte[] srcBuffer, short srcLength, APDU apdu) { if (srcLength > MAX_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Send data - byte[] srcBuffer = context.getBuffer(); apdu.setOutgoing(); apdu.setOutgoingLength(srcLength); apdu.sendBytesLong(srcBuffer, (short) 0, srcLength); } - /** - * Receives data, which can be extended data, as requested by the command instance. - * - * @param context of current command. - */ - public void receiveIncoming(KMContext context, APDU apdu) { + /** Receives data, which can be extended data, as requested by the command instance. */ + private short receiveIncoming(byte[] destBuffer, APDU apdu) { // Initialize source byte[] srcBuffer = apdu.getBuffer(); // Initialize destination - byte[] destBuffer = context.getBuffer(); short destOffset = (short) 0; - // Receive data short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); short srcLength = apdu.getIncomingLength(); if (srcLength > MAX_LENGTH) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } while (recvLen > 0) { Util.arrayCopyNonAtomic(srcBuffer, srcOffset, destBuffer, destOffset, recvLen); destOffset += recvLen; recvLen = apdu.receiveBytes(srcOffset); } - // Update the Context - context.setBufferLength(srcLength); + return srcLength; } - /** - * Getter for keymaster state. - * - * @return keymasterState - current state of the applet. - */ - private byte getKeymasterState() { - return keymasterState; + // Commands + private void handle(byte ins, APDU apdu) { + switch (ins) { + case INS_GENERATE_KEY_CMD: + processGenerateKey(apdu); + break; + case INS_IMPORT_KEY_CMD: + processImportKeyCmd(apdu); + break; + case INS_IMPORT_WRAPPED_KEY_CMD: + processImportWrappedKeyCmd(apdu); + break; + case INS_EXPORT_KEY_CMD: + processExportKeyCmd(apdu); + break; + case INS_ATTEST_KEY_CMD: + processAttestKeyCmd(apdu); + break; + case INS_UPGRADE_KEY_CMD: + processUpgradeKeyCmd(apdu); + break; + case INS_DELETE_KEY_CMD: + processDeleteKeyCmd(apdu); + break; + case INS_DELETE_ALL_KEYS_CMD: + processDeleteAllKeysCmd(apdu); + break; + case INS_ADD_RNG_ENTROPY_CMD: + processAddRngEntropyCmd(apdu); + break; + case INS_COMPUTE_SHARED_HMAC_CMD: + processComputeSharedHmacCmd(apdu); + break; + case INS_DESTROY_ATT_IDS_CMD: + processDestroyAttIdsCmd(apdu); + break; + case INS_VERIFY_AUTHORIZATION_CMD: + processVerifyAuthenticationCmd(apdu); + break; + case INS_GET_HMAC_SHARING_PARAM_CMD: + processGetHmacSharingParamCmd(apdu); + break; + case INS_GET_KEY_CHARACTERISTICS_CMD: + processGetKeyCharacteristicsCmd(apdu); + break; + case INS_GET_HW_INFO_CMD: + processGetHwInfoCmd(apdu); + break; + case INS_BEGIN_OPERATION_CMD: + processBeginOperationCmd(apdu); + break; + case INS_UPDATE_OPERATION_CMD: + processUpdateOperationCmd(apdu); + break; + case INS_FINISH_OPERATION_CMD: + processFinishOperationCmd(apdu); + break; + case INS_ABORT_OPERATION_CMD: + processAbortOperationCmd(apdu); + break; + case INS_PROVISION_CMD: + processProvisionCmd(apdu); + break; + default: + ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); + } } - /** Setter for keymaster state. */ - private void setKeymasterState(byte keymasterState) { - this.keymasterState = keymasterState; + + private short processProvisionCmd(APDU apdu) { + // Receive the incoming request fully from the master. + short length = receiveIncoming(buffer, apdu); + // Re-purpose the apdu buffer as scratch pad. + byte[] scratchPad = apdu.getBuffer(); + Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) apdu.getBuffer().length, (byte) 0); + // Argument 1 + KMKeyParameters keyparams = KMKeyParameters.instance(); + // Argument 2 + KMEnum keyFormat = KMEnum.instance().setType(KMType.KEY_FORMAT); + // Argument 3 + KMByteBlob keyBlob = KMByteBlob.instance(); + // Array of expected arguments + KMArray argsProto = + KMArray.instance((short) 3) + .add((short) 0, keyparams) + .add((short) 1, keyFormat) + .add((short) 2, keyBlob); + // Decode the argument + KMArray args = decoder.decode(argsProto, buffer, (short) 0, length); + // TODO execute the function + // Change the state to ACTIVE + if (keymasterState == KMKeymasterApplet.FIRST_SELECT_STATE) { + keymasterState = KMKeymasterApplet.ACTIVE_STATE; + } + // nothing to return + return 0; + } + + private void processGetHwInfoCmd(APDU apdu) { + // No arguments expected + // Make the response + KMArray resp = + KMArray.instance((short) 3) + .add((short) 0, KMEnum.instance(KMType.HARDWARE_TYPE, KMType.STRONGBOX)) + .add( + (short) 1, + KMByteBlob.instance( + JavacardKeymasterDevice, (short) 0, (short) JavacardKeymasterDevice.length)) + .add((short) 2, KMByteBlob.instance(Google, (short) 0, (short) Google.length)); + // Reuse the buffer + Util.arrayFillNonAtomic(buffer, (short) 0, MAX_LENGTH, (byte) 0); + // Encode the response + short len = encoder.encode(resp, buffer, (short) 0, MAX_LENGTH); + sendOutgoing(buffer, len, apdu); + } + + private short processAddRngEntropyCmd(APDU apdu) { + // Receive the incoming request fully from the master. + short length = receiveIncoming(buffer, apdu); + // Re-purpose the apdu buffer as scratch pad. + byte[] scratchPad = apdu.getBuffer(); + Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) apdu.getBuffer().length, (byte) 0); + // Argument 1 + KMArray argsProto = KMArray.instance((short) 1).add((short) 0, KMByteBlob.instance()); + + // Decode the argument + KMArray args = decoder.decode(argsProto, buffer, (short) 0, length); + // Process + KMByteBlob blob = (KMByteBlob) args.get((short) 0); + // Maximum 2KiB of seed is allowed. + if (blob.length() > MAX_SEED_SIZE) { + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); + } + // Get existing entropy pool. + byte[] entPool = KMUtil.getEntropyPool(); + // Create new temporary pool. + byte[] heapRef = repository.getByteHeapRef(); + short poolStart = repository.newByteArray((short) entPool.length); + // Populate the new pool with the entropy which is derived from current entropy pool. + KMUtil.newRandomNumber(heapRef, poolStart, (short) entPool.length); + // Copy the entropy to the current pool - updates the entropy pool. + Util.arrayCopy(heapRef, poolStart, entPool, (short) 0, (short) entPool.length); + short index = 0; + short randIndex = 0; + // Mix (XOR) the seed received from the master in the entropy pool - 32 bytes (entPool.length). + // at a time. + while (index < blob.length()) { + entPool[randIndex] = (byte) (entPool[randIndex] ^ blob.get(index)); + randIndex++; + index++; + if (randIndex >= entPool.length) { + randIndex = 0; + } + } + // Nothing to return + return 0; + } + + private short processAbortOperationCmd(APDU apdu) { + return 0; + } + + private short processFinishOperationCmd(APDU apdu) { + return 0; + } + + private short processUpdateOperationCmd(APDU apdu) { + return 0; + } + + private short processBeginOperationCmd(APDU apdu) { + return 0; + } + + private short processGetKeyCharacteristicsCmd(APDU apdu) { + return 0; + } + + private short processGetHmacSharingParamCmd(APDU apdu) { + return 0; + } + + private short processVerifyAuthenticationCmd(APDU apdu) { + return 0; + } + + private short processDestroyAttIdsCmd(APDU apdu) { + return 0; + } + + private short processComputeSharedHmacCmd(APDU apdu) { + return 0; + } + + private short processDeleteAllKeysCmd(APDU apdu) { + return 0; + } + + private short processDeleteKeyCmd(APDU apdu) { + return 0; + } + + private short processUpgradeKeyCmd(APDU apdu) { + return 0; + } + + private short processAttestKeyCmd(APDU apdu) { + return 0; + } + + private short processExportKeyCmd(APDU apdu) { + return 0; + } + + private short processImportWrappedKeyCmd(APDU apdu) { + return 0; + } + + private short processImportKeyCmd(APDU apdu) { + return 0; + } + + private short processGenerateKey(APDU apdu) { + return 0; } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMMessenger.java b/Applet/Applet/src/com/android/javacard/keymaster/KMMessenger.java deleted file mode 100644 index 3eb4b548..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMMessenger.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public interface KMMessenger { - void receiveIncoming(KMContext context); - void sendOutgoing(KMContext context); -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java index 5aaa9948..d1671328 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java @@ -23,12 +23,12 @@ public class KMOperationState { private KMOperationState() { operationHandle = null; } - +/* public static KMOperationState instance(KMContext context) { // TODO make operation handle return context.getRepository().newOperationState(); } - +*/ public static void create(KMOperationState[] opStateRefTable) { byte index = 0; while (index < opStateRefTable.length) { @@ -44,9 +44,11 @@ public KMInteger getOperationHandle() { public void setOperationHandle(KMInteger operationHandle) { this.operationHandle = operationHandle; } - +/* public void release(KMContext context) { // TODO release handle context.getRepository().releaseOperationState(this); } + + */ } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMProvisionCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMProvisionCmd.java deleted file mode 100644 index d1911f7e..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMProvisionCmd.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMProvisionCmd extends KMAbstractCmd { - public static final byte INS_PROVISION_CMD = 0x23; - - @Override - public byte getIns() { - return INS_PROVISION_CMD; - } - - @Override - public KMArray process(KMArray args, KMContext context) { - KMKeyParameters arg1 = (KMKeyParameters)args.get((short)0); - KMEnum arg2 = (KMEnum)args.get((short)1); - KMByteBlob arg3 = (KMByteBlob)args.get((short)2); - provision(arg1, arg2.getVal(),arg3); - context.setKeymasterState(KMKeymasterApplet.ACTIVE_STATE); - //nothing to return - return null; - } - - // TODO implement functionality - private void provision(KMKeyParameters params, byte keyFormat, KMByteBlob keyBlob){ - } - - @Override - protected boolean validateState(byte state) { - return (KMKeymasterApplet.FIRST_SELECT_STATE == state); - } - - // Uses import key command signature but does not return anything back. - protected KMArray getExpectedArgs() { - // Argument 1 - KMKeyParameters keyparams = KMKeyParameters.instance(); - // Argument 2 - KMEnum keyFormat = KMEnum.instance().setType(KMType.KEY_FORMAT); - // Argument 3 - KMByteBlob keyBlob = KMByteBlob.instance(); - // Array of expected arguments - return KMArray.instance((short) 3) - .add((short) 0, keyparams) - .add((short) 1, keyFormat) - .add((short) 2, keyBlob); - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java index 36d8f6f7..b71aea01 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.Util; import javacard.security.AESKey; @@ -27,20 +28,14 @@ // to handle onInstall and onSelect. public class KMRepository { - private static final byte CMD_TABLE_LENGTH = 20; private static final byte REF_TABLE_SIZE = 5; private static final short HEAP_SIZE = 0x1000; private static final byte INT_TABLE_SIZE = 10; private static final byte TYPE_ARRAY_SIZE = 100; private static final byte INT_SIZE = 4; private static final byte LONG_SIZE = 8; - private static final short ENTROPY_POOL_SIZE = 32; - - private KMCommand[] commandTable = null; - private KMContext context = null; - private byte[] buffer = null; + private static KMRepository repository; private AESKey masterKey = null; - private boolean contextLocked = false; private KMEncoder encoder = null; private KMDecoder decoder = null; @@ -91,38 +86,23 @@ public class KMRepository { private byte[] entropyPool = null; private byte[] counter; - public void initialize() { + public static KMRepository instance() { + if (repository == null) { + repository = new KMRepository(); + } + return repository; + } + + public KMRepository(){ + initialize(); + } + + private void initialize() { // Initialize buffers and context. JCSystem.beginTransaction(); encoder = new KMEncoder(); decoder = new KMDecoder(); - buffer = new byte[KMKeymasterApplet.MAX_LENGTH]; - context = new KMContext(); - context.setRepository(this); - contextLocked = false; operationStateTable = new KMOperationState[4]; - // Initialize command table. - commandTable = new KMCommand[CMD_TABLE_LENGTH]; - commandTable[0] = new KMProvisionCmd(); - commandTable[1] = new KMGenerateKeyCmd(); - commandTable[2] = new KMImportKeyCmd(); - commandTable[3] = new KMExportKeyCmd(); - commandTable[4] = new KMComputeSharedHmacCmd(); - commandTable[5] = new KMBeginOperationCmd(); - commandTable[6] = new KMUpdateOperationCmd(); - commandTable[7] = new KMFinishOperationCmd(); - commandTable[8] = new KMAbortOperationCmd(); - commandTable[9] = new KMVerifyAuthorizationCmd(); - commandTable[10] = new KMAddRngEntropyCmd(); - commandTable[11] = new KMImportWrappedKeyCmd(); - commandTable[12] = new KMAttestKeyCmd(); - commandTable[13] = new KMUpgradeKeyCmd(); - commandTable[14] = new KMDeleteKeyCmd(); - commandTable[15] = new KMDeleteAllKeysCmd(); - commandTable[16] = new KMDestroyAttestationIdsCmd(); - commandTable[17] = new KMGetHWInfoCmd(); - commandTable[18] = new KMGetKeyCharacteristicsCmd(); - commandTable[19] = new KMGetHmacSharingParametersCmd(); // Initialize masterkey - AES 256 bit key. if (masterKey == null) { masterKey = @@ -176,8 +156,6 @@ public void initialize() { uint64Array[index] = new byte[LONG_SIZE]; index++; } - entropyPool = new byte[ENTROPY_POOL_SIZE]; - counter = new byte[8]; JCSystem.commitTransaction(); } @@ -190,26 +168,6 @@ public KMDecoder getDecoder() { return decoder; } - public KMCommand getCommand(byte ins) throws KMException { - short cmdIndex = 0; - while (cmdIndex < CMD_TABLE_LENGTH) { - if (commandTable[cmdIndex].getIns() == ins) { - return commandTable[cmdIndex]; - } - cmdIndex++; - } - throw new KMException(ISO7816.SW_INS_NOT_SUPPORTED); - } - - public KMContext getContext() throws KMException { - if (!contextLocked) { - contextLocked = true; - return context; - } else { - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); - } - } - public void onUninstall() { masterKey = null; } @@ -219,11 +177,8 @@ public void onProcess() { } private void reset() { - contextLocked = false; - Util.arrayFillNonAtomic(buffer, (short) 0, (short) buffer.length, (byte) 0); - Util.arrayFillNonAtomic(byteHeap, (short) 0, (short) buffer.length, (byte) 0); + Util.arrayFillNonAtomic(byteHeap, (short) 0, (short) byteHeap.length, (byte) 0); byteHeapIndex = 0; - Util.arrayFillNonAtomic(buffer, (short) 0, (short) buffer.length, (byte) 0); short index = 0; while (index < typeRefTable.length) { typeRefTable[index] = null; @@ -285,10 +240,6 @@ public void onSelect() { // Nothing to be done currently. } - public byte[] getBuffer() { - return buffer; - } - public AESKey getMasterKey() { return masterKey; } @@ -298,7 +249,7 @@ public byte[] newIntegerArray(short length) { if (length == 4) { if (uint32Index >= uint32Array.length) { // TODO this is placeholder exception value. This needs to be replaced by 910E, 91A1 or 9210 - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } byte[] ret = (byte[]) uint32Array[uint32Index]; uint32Index++; @@ -306,20 +257,21 @@ public byte[] newIntegerArray(short length) { } else if (length == 8) { if (uint64Index >= uint64Array.length) { // TODO this is placeholder exception value. This needs to be replaced by 910E, 91A1 or 9210 - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } byte[] ret = (byte[]) uint64Array[uint64Index]; uint64Index++; return ret; } else { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } + return null;// this will never be executed. } public KMByteBlob newByteBlob() { if (blobRefIndex >= byteBlobRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMByteBlob ret = byteBlobRefTable[blobRefIndex]; blobRefIndex++; @@ -329,7 +281,7 @@ public KMByteBlob newByteBlob() { public KMInteger newInteger() { if (intRefIndex >= integerRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMInteger ret = integerRefTable[intRefIndex]; intRefIndex++; @@ -339,7 +291,7 @@ public KMInteger newInteger() { public KMEnumTag newEnumTag() { if (enumTagRefIndex >= enumTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMEnumTag ret = enumTagRefTable[enumTagRefIndex]; enumTagRefIndex++; @@ -349,7 +301,7 @@ public KMEnumTag newEnumTag() { public KMEnumArrayTag newEnumArrayTag() { if (enumArrayTagRefIndex >= enumArrayTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMEnumArrayTag ret = enumArrayTagRefTable[enumArrayTagRefIndex]; enumArrayTagRefIndex++; @@ -359,7 +311,7 @@ public KMEnumArrayTag newEnumArrayTag() { public KMIntegerTag newIntegerTag() { if (intTagRefIndex >= intTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMIntegerTag ret = intTagRefTable[intTagRefIndex]; intTagRefIndex++; @@ -369,7 +321,7 @@ public KMIntegerTag newIntegerTag() { public KMIntegerArrayTag newIntegerArrayTag() { if (intArrayTagRefIndex >= intArrayTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMIntegerArrayTag ret = intArrayTagRefTable[intArrayTagRefIndex]; intArrayTagRefIndex++; @@ -379,7 +331,7 @@ public KMIntegerArrayTag newIntegerArrayTag() { public KMBoolTag newBoolTag() { if (boolTagRefIndex >= boolTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMBoolTag ret = boolTagRefTable[boolTagRefIndex]; boolTagRefIndex++; @@ -389,7 +341,7 @@ public KMBoolTag newBoolTag() { public KMByteTag newByteTag() { if (byteTagRefIndex >= byteTagRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMByteTag ret = byteTagRefTable[byteTagRefIndex]; byteTagRefIndex++; @@ -399,7 +351,7 @@ public KMByteTag newByteTag() { public KMKeyParameters newKeyParameters() { if (keyParametersRefIndex >= keyParametersRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMKeyParameters ret = keyParametersRefTable[keyParametersRefIndex]; keyParametersRefIndex++; @@ -409,7 +361,7 @@ public KMKeyParameters newKeyParameters() { public KMArray newArray() { if (arrayRefIndex >= arrayRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMArray ret = arrayRefTable[arrayRefIndex]; arrayRefIndex++; @@ -419,7 +371,7 @@ public KMArray newArray() { public KMKeyCharacteristics newKeyCharacteristics() { if (keyCharRefIndex >= keyCharRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMKeyCharacteristics ret = keyCharRefTable[keyCharRefIndex]; keyCharRefIndex++; @@ -429,7 +381,7 @@ public KMKeyCharacteristics newKeyCharacteristics() { public KMHardwareAuthToken newHwAuthToken() { if (hwAuthTokenRefIndex >= hwAuthTokenRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMHardwareAuthToken ret = hwAuthTokenRefTable[hwAuthTokenRefIndex]; hwAuthTokenRefIndex++; @@ -439,7 +391,7 @@ public KMHardwareAuthToken newHwAuthToken() { public KMHmacSharingParameters newHmacSharingParameters() { if (hmacSharingParamsRefIndex >= hmacSharingParamsRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMHmacSharingParameters ret = hmacSharingParamsRefTable[hmacSharingParamsRefIndex]; hmacSharingParamsRefIndex++; @@ -449,7 +401,7 @@ public KMHmacSharingParameters newHmacSharingParameters() { public KMVerificationToken newVerificationToken() { if (verTokenRefIndex >= verTokenRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMVerificationToken ret = verTokenRefTable[verTokenRefIndex]; verTokenRefIndex++; @@ -459,7 +411,7 @@ public KMVerificationToken newVerificationToken() { public KMOperationState newOperationState() { if (opStateRefIndex >= opStateRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMOperationState ret = operationStateTable[opStateRefIndex]; opStateRefIndex++; @@ -469,14 +421,14 @@ public KMOperationState newOperationState() { public void releaseOperationState(KMOperationState state){ opStateRefIndex--; if(opStateRefIndex <0){ - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } opStateRefTable[opStateRefIndex] = state; } public KMVector newVector() { if (vectorRefIndex >= vectorRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMVector ret = vectorRefTable[vectorRefIndex]; vectorRefIndex++; @@ -486,7 +438,7 @@ public KMVector newVector() { public KMEnum newEnum() { if (enumRefIndex >= enumRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } KMEnum ret = enumRefTable[enumRefIndex]; enumRefIndex++; @@ -504,7 +456,7 @@ public byte[] getByteHeapRef(){ public short newTypeArray(short length) { if (((short) (typeRefIndex + length)) >= typeRefTable.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } typeRefIndex += length; return (short) (typeRefIndex - length); @@ -513,13 +465,9 @@ public short newTypeArray(short length) { public short newByteArray(short length) { if (((short) (byteHeapIndex + length)) >= byteHeap.length) { // TODO this is placeholder exception value. - throw new KMException(ISO7816.SW_CONDITIONS_NOT_SATISFIED); + ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } byteHeapIndex += length; return (short) (byteHeapIndex - length); } - - public byte[] getEntropyPool() { - return entropyPool; - } } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMUpdateOperationCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMUpdateOperationCmd.java deleted file mode 100644 index 5b1e58f6..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMUpdateOperationCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMUpdateOperationCmd extends KMAbstractCmd { - public static final byte INS_UPDATE_OPERATION_CMD = 0x20; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_UPDATE_OPERATION_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMUpgradeKeyCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMUpgradeKeyCmd.java deleted file mode 100644 index d883068f..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMUpgradeKeyCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMUpgradeKeyCmd extends KMAbstractCmd { - public static final byte INS_UPGRADE_KEY_CMD = 0x15; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_UPGRADE_KEY_CMD; - } -} diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMUtil.java b/Applet/Applet/src/com/android/javacard/keymaster/KMUtil.java index 5b42ae9d..0d1080df 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMUtil.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMUtil.java @@ -1,6 +1,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; import javacard.framework.Util; import javacard.security.AESKey; import javacard.security.CryptoException; @@ -9,27 +10,25 @@ import javacardx.crypto.Cipher; public class KMUtil { + private static final short ENTROPY_POOL_SIZE = 16; // simulator does not support 256 bit aes keys public static final byte AES_BLOCK_SIZE = 16; - private static KMRepository repository = null; + public static final byte[] aesICV = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; private static byte[] counter; - private static boolean initialized = false; private static AESKey aesKey; - private static Cipher aesEcb; - - public static void init(KMRepository repo) { - if (!initialized) { - KMUtil.repository = repo; - counter = repo.newIntegerArray((short) 8); - KMUtil.initEntropyPool(repo.getEntropyPool()); + private static Cipher aesCbc; + private static byte[] entropyPool; + public static void init() { + entropyPool = new byte[ENTROPY_POOL_SIZE]; + counter = KMRepository.instance().newIntegerArray((short) 8); + KMUtil.initEntropyPool(entropyPool); try { - aesEcb = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, false); + //Note: ALG_AES_BLOCK_128_CBC_NOPAD not supported by simulator. + aesCbc = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); } catch (CryptoException exp) { // TODO change this to proper error code - throw new KMException(ISO7816.SW_UNKNOWN); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } - aesKey = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_256, false); - initialized = true; - } + aesKey = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false); } public static void initEntropyPool(byte[] pool) { @@ -40,26 +39,31 @@ public static void initEntropyPool(byte[] pool) { } try { trng = RandomData.getInstance(RandomData.ALG_TRNG); + trng.nextBytes(pool, (short) 0, (short) pool.length); } catch (CryptoException exp) { if (exp.getReason() == CryptoException.NO_SUCH_ALGORITHM) { //TODO change this when possible // simulator does not support TRNG algorithm. So, PRNG algorithm (deprecated) is used. trng = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM); + trng.nextBytes(pool, (short) 0, (short) pool.length); } else { // TODO change this to proper error code - throw new KMException(ISO7816.SW_UNKNOWN); + ISOException.throwIt(ISO7816.SW_UNKNOWN); } } - trng.nextBytes(pool, (short) 0, (short) pool.length); + } // Generate a secure random number from existing entropy pool. This uses aes ecb algorithm with // 8 byte counter and 16 byte block size. public static void newRandomNumber(byte[] num, short startOff, short length) { + KMRepository repository = KMRepository.instance(); byte[] bufPtr = repository.getByteHeapRef(); short countBufInd = repository.newByteArray(AES_BLOCK_SIZE); short randBufInd = repository.newByteArray(AES_BLOCK_SIZE); short len = AES_BLOCK_SIZE; + aesKey.setKey(entropyPool, (short) 0); + aesCbc.init(aesKey, Cipher.MODE_ENCRYPT, aesICV, (short)0, (short)16); while (length > 0) { if (length < len ) len = length; // increment counter by one @@ -67,9 +71,7 @@ public static void newRandomNumber(byte[] num, short startOff, short length) { // copy the 8 byte counter into the 16 byte counter buffer. Util.arrayCopy(counter, (short) 0, bufPtr, countBufInd, (short) counter.length); // encrypt the counter buffer with existing entropy which forms the aes key. - aesKey.setKey(repository.getEntropyPool(), (short) 0); - aesEcb.init(aesKey, Cipher.MODE_ENCRYPT); - aesEcb.doFinal(bufPtr, countBufInd, AES_BLOCK_SIZE, bufPtr, randBufInd); + aesCbc.doFinal(bufPtr, countBufInd, AES_BLOCK_SIZE, bufPtr, randBufInd); // copy the encrypted counter block to buffer passed in the argument Util.arrayCopy(bufPtr, randBufInd, num, startOff, len); length = (short) (length - len); @@ -98,4 +100,9 @@ private static void incrementCounter() { } } } + + public static byte[] getEntropyPool() { + return entropyPool; + } + } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java b/Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java index f52fae55..d47c80e2 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java +++ b/Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java @@ -17,6 +17,7 @@ package com.android.javacard.keymaster; import javacard.framework.ISO7816; +import javacard.framework.ISOException; public class KMVerificationToken extends KMType { public static final byte CHALLENGE = 0x00; @@ -61,7 +62,7 @@ public static KMVerificationToken instance() { public static KMVerificationToken instance(KMArray vals) { if (vals.length() != 5) { - throw new KMException(ISO7816.SW_WRONG_LENGTH); + ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KMVerificationToken inst = repository.newVerificationToken(); inst.vals = vals; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMVerifyAuthorizationCmd.java b/Applet/Applet/src/com/android/javacard/keymaster/KMVerifyAuthorizationCmd.java deleted file mode 100644 index 33289b44..00000000 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMVerifyAuthorizationCmd.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright(C) 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. - */ - -package com.android.javacard.keymaster; - -public class KMVerifyAuthorizationCmd extends KMAbstractCmd { - public static final byte INS_VERIFY_AUTHORIZATION_CMD = 0x1B; - - @Override - protected KMArray getExpectedArgs() { - return null; - } - - @Override - protected KMArray process(KMArray args, KMContext context) { - return null; - } - - @Override - public byte getIns() { - return INS_VERIFY_AUTHORIZATION_CMD; - } -} From f99cbfb913c1e1e3ef505d2309086445a9f4c353 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 29 Mar 2020 04:44:13 +0530 Subject: [PATCH 04/58] Restructured keymaster from 4.0 to 4.1 implementation --- ...hardware.keymaster@4.0-service.javacard.rc | 4 - .../4.1/.JavacardKeymaster4Device.cpp.swo | Bin 0 -> 16384 bytes .../4.1/.JavacardKeymaster4Device.cpp.swp | Bin 0 -> 16384 bytes .../{4.0 => 4.1}/JavacardKeymaster4Device.cpp | 40 +++++-- HAL/keymaster/4.1/Operation.cpp | 38 +++++++ ...hardware.keymaster@4.1-service.javacard.rc | 4 + ...rdware.keymaster@4.1-service.javacard.xml} | 2 +- HAL/keymaster/{4.0 => 4.1}/service.cpp | 4 +- HAL/keymaster/Android.bp | 39 +++---- .../include/JavacardKeymaster4Device.h | 105 +++++++----------- HAL/keymaster/include/Operation.h | 53 +++++++++ 11 files changed, 190 insertions(+), 99 deletions(-) delete mode 100644 HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc create mode 100644 HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo create mode 100644 HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp rename HAL/keymaster/{4.0 => 4.1}/JavacardKeymaster4Device.cpp (85%) create mode 100644 HAL/keymaster/4.1/Operation.cpp create mode 100644 HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.rc rename HAL/keymaster/{4.0/android.hardware.keymaster@4.0-service.javacard.xml => 4.1/android.hardware.keymaster@4.1-service.javacard.xml} (90%) rename HAL/keymaster/{4.0 => 4.1}/service.cpp (88%) create mode 100644 HAL/keymaster/include/Operation.h diff --git a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc b/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc deleted file mode 100644 index af0342e9..00000000 --- a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.keymaster-4-0 /vendor/bin/hw/android.hardware.keymaster@4.0-service.javacard - class early_hal - user nobody - group drmrpc diff --git a/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo b/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo new file mode 100644 index 0000000000000000000000000000000000000000..d27a6c47d35a42a192926f8e1442f2e601839c67 GIT binary patch literal 16384 zcmeI3?T;Hr9mlsVkf)}PZ$RQ zX2<6^<uK*!lp-S+gpsi+(@&py>X`NR9oM%ks}nJ)lW%qv zORJ@|rRv=L=RZ5O=rvuTT?jlWxK|M!>9Tp7T~SO1)VF$Pcw4Et36 zr2S>ONnI+vb7|_SCAP_3mUqK&YJ(=zC}0%mE6`Dm6AOpeKQn(ap6U;rG!ZCNjY7r}Qx z4_pCt@D;EMJ_ZhhL*O9z!y(Ih1H2Ai0IR?ON5K8yUT_b1;h<%G7hDBRz<>wdIshNQ zPr&!U*8m4i&;Z}xZ&_al3@m`7;Qf7;^;hs3xDI{^UItHsCGaqK5d7mKC=1>L&w@*! z3g*Bk!69$}><3SM7+QcM-~f2d1gxz)_IdV_%Gu)=TS^<)ztLi+g^}tq-Txxo9&bxm)4h za85|0s4Jv5mJ#u*EGer0B#)3z(3Ln~!h_~2m9!n@b$Z%-QU(W4Hc$YEO?Jvn???7o zU)0Bn)D%hTiAyqlXl02iI#kfMNwvIGCcGW`tjz*tt;K4b-h>)w$fWZwj)NP7R2Q`m zam}-?2qHyd!8VzDy2AstP*Z1)lHt~KWO~8AzuKWGCAWncD+DKFK^czhpz%?eb3_~V zxl<5lptA;22Rk>XWf}4kV}WFYf;^4IXip<(gY_O2vQ5?S@X_5hJW5b-tjlz%?Y>2c z9R|>Cb}K|2?N1~P>Y6p1BgpAHLy*}2YphqcM+3@ek5XxI^DS#SBGb*Z*m*ARS)nEi zn52rq^4)7RaMN^mm!%YPQFx3zy*0EHO?2AZ^_0%)o;I(k=dA_JXhjybs9jk?ui zd!GPqi~2qbn(1)QCS{g^C6abjt132Fkk3+gCrPMRRJ{O1RdIny-WXm#lK~+@-H%)Z zD>U%@)RH}qi_N&90&EtNUyUoC&DN0ZSRP7`dtL=o1)M&kgJ>;&!r@tVtWojXri<%Tj8vGonov z4d3B*6!#^@tsklAWei%_sD; zUtY;hqR68DQEHEV^wTMObzt0=wdRE*7gR<@GALSXf&tl&Zz$3MsFV#d2w>SS^-I z`1U9%l%62xilwC-VH}1?!mfl8vJteY9pKFC8|Co`&*pWkBi^{(ghynsfCyj&nJH9A zu`)x>7AnO`E;eaB@O9;qUG8u!Mx@>&c+&N`OY1&^UtQfUZAykbB?u4jn9CI$%#lbm zlwP8BJ#k%nkI_;pbZooZ?dBZD$6J4ar!;I?FrE#ZQ3KE zt|;oKSlvQ=YYa(FRop}`DH{kyaI_so;An%xRCdK>q0$EG#nI<9z@ z_heOyOU#WOz-+Vh{{L<4lP_Tpt@r=w`+Em_{3GBX_#^iBuYhO4HLwLf3ho5I!M^@g z@N4iK_Uj?|D)<8U1o#{3{WJI-_&In9{0RII`~Z9d=(ag9mr=kdU=%P47zK<1MggOM zQQ&_^fh|I?x87klY>npVjq`*c_s!pv48)9*t#ua1OQPIad@ReD7WUKiA)g0vsBAdq zr1ORX!DFvP5);CX3`KO?(Y`us@}L~fI!>~=cARu~?Ks)?+HoM@oa3BBc(30sN!m~2 zc{{u>!QDH){@8s}Y4{V7u~e+Iz1>x^GBwJW_&ypL8h#hDi-t}*P8O2R!rc=iZns$B zv=}#|((j!WLMmmaqL@cD>Ht=Fi!^O;2@79wTLF@`17GHlXMsS8z(%G8~^|S literal 0 HcmV?d00001 diff --git a/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp b/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..5e8ec6bb35e1502b45664da232eb8cfff91c80e3 GIT binary patch literal 16384 zcmeI3?~fZt8OJx2wxMY#&>jBY{9yoWGo^u!bIQtUHi#X%mu|2)@ z&ayi`$E{NO3Pcg~AK*n1Z`v1aU+@kI310B7<(CvB{)6&EeNhP{BtrPk{_?N0vv)13 z1as0yj%R0Qp7}mAv-3ROG#0OvE|YWlMFW4IFpRA~^{?H!&pWov45J$`Ulrf&uT|CSC~g(@(r?T8#juVwTxWTW?Q@IeEzg_T zg}$g2&mKr5gX&0viVKct zI-0 zi5rA3uPPhDmgg~b-v48d9E&3PDgg8z30g6ih}{osEId5_M(atl}wYm zwh!Y?vyE3rdemp8nZ8zHnpc+Vi>3)Fwy94$3@@I*#IBo&8I}e)qRjvDG9>h95cGs^ zSGhe@+Ta5B`rHbO$F-J%lT&jXQx;Yq+CO8G-%Zzpy?W%O)?zO6sbsMHgVuYf>Di)WbIiK$3x8GEj68pH zWGYV;(9XOe9nykXdl$9s9k;daN?&*rk`5-0vh95=U#m?Whqq=I|gO1r79cmqIdr)_(HtuE_Hb_TS?g3&vyuH;Toa71ggJiV`=cJ6c+ ztOrc0is^W^Do@vI#iz+!++jXBjONo8zP_A4dq$nR^V07IvOkB@JqAY>7Kp<;T!!0g zfU~L1d?MS7Y~j^sH(>d&N|mwULbyJv6nMPl~x~(n-Mp}^2cd@t$9tIsA1b7?- z1a^h(TrJf$D!VmuwYalWEZ0iwRZ`g@tCjLvsaC3#@$DihmY*S;rSe*iFb+d}!ftpz zWFzQP4S+K{GRo!w4#f@ZN%o}Oga>4}f^cC3nJZRFsX9k46sx6bE;MP^byVX%`*xRO zV?gLdc8cw zlx(xS@LL76r_>AzTcy?Ya&`U865f7KZhJ;_Nr(1{Xh@3oDfU1Q-`uDi~;!!&G*|VxCk6sx8#v)Wv$}LBio?BIRP=4$D>yZB4wMBY4Uy*AduB=GAV=k$Rt`94=eeo=_!U15l87lt2jo9{e z#K9{5e>@B}5tkySzXponQE)GK2QmE5!4JVcxDGCZO>hbP5%Kyj!B2q=R9sKNb?`}0 zL)^Xs?jSC|4gLjQ0WX0~Py!p^Gl8Lx|(K8;14BYDcN}Y>mv$oWx@vk7Gy0&Ctjz1(gU~xkTC;d^P;yV4q zc@;r~iVnk-5a+|fB-n6~5(UFKY(fIAoSu+4^u)lAG?NqKXj#n+E*!yS#uk~jHuyCllw_i}!Sz(nq)s+N VW^c2H*|4)L?Hm#lO3v|p`#-du(mMbE literal 0 HcmV?d00001 diff --git a/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp similarity index 85% rename from HAL/keymaster/4.0/JavacardKeymaster4Device.cpp rename to HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 786481f9..0f3d0584 100644 --- a/HAL/keymaster/4.0/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -25,8 +25,10 @@ /* TODO Remove below UNUSED */ #define UNUSED(a) a=a +namespace android { +namespace hardware { namespace keymaster { -namespace V4_0 { +namespace V4_1 { JavacardKeymaster4Device::JavacardKeymaster4Device() { // TODO @@ -35,7 +37,7 @@ JavacardKeymaster4Device::JavacardKeymaster4Device() { JavacardKeymaster4Device::~JavacardKeymaster4Device() { } -// Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. +// Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { _hidl_cb(SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); return Void(); @@ -204,12 +206,34 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device return ::android::hardware::keymaster::V4_0::ErrorCode {}; } +// Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. +Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) { + // TODO implement + UNUSED(passwordOnly); + size_t challenge = verificationToken.challenge; + UNUSED(challenge); + return ::android::hardware::keymaster::V4_1::ErrorCode {}; +} + +Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::earlyBootEnded() { + // TODO implement + return ::android::hardware::keymaster::V4_1::ErrorCode {}; +} -// Methods from ::android::hidl::base::V1_0::IBase follow. +Return JavacardKeymaster4Device::beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, beginOp_cb _hidl_cb) { + // TODO implement + UNUSED(purpose); + size_t size = keyBlob.size(); + size = inParams.size(); + uint64_t challenge = authToken.challenge; + UNUSED(challenge); + UNUSED(size); + UNUSED(_hidl_cb); -//IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) { - //return new JavacardKeymaster4Device(); -//} -// -} // namespace android::hardware::keymaster::implementation + return Void(); } + +} // namespace V4_1 +} // namespace keymaster +} // namespace hardware +} // namespace android diff --git a/HAL/keymaster/4.1/Operation.cpp b/HAL/keymaster/4.1/Operation.cpp new file mode 100644 index 00000000..14b6a473 --- /dev/null +++ b/HAL/keymaster/4.1/Operation.cpp @@ -0,0 +1,38 @@ +/* + ** + ** 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 +#define UNUSED(a) a=a + +namespace android { +namespace hardware { +namespace keymaster { +namespace V4_1 { + +// Methods from ::android::hardware::keymaster::V4_1::IOperation follow. +::android::hardware::Return Operation::getOperationChallenge(getOperationChallenge_cb _hidl_cb) { + // TODO implement + UNUSED(_hidl_cb); + return Void(); +} + + +} // namespace V4_1 +} // namespace keymaster +} // namespace hardware +} // namespace android diff --git a/HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.rc b/HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.rc new file mode 100644 index 00000000..1094c090 --- /dev/null +++ b/HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.rc @@ -0,0 +1,4 @@ +service vendor.keymaster-4-1 /vendor/bin/hw/android.hardware.keymaster@4.1-service.javacard + class early_hal + user nobody + group drmrpc diff --git a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml b/HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.xml similarity index 90% rename from HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml rename to HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.xml index aa30707c..4fb320a6 100644 --- a/HAL/keymaster/4.0/android.hardware.keymaster@4.0-service.javacard.xml +++ b/HAL/keymaster/4.1/android.hardware.keymaster@4.1-service.javacard.xml @@ -2,7 +2,7 @@ android.hardware.keymaster hwbinder - 4.0 + 4.1 IKeymasterDevice default diff --git a/HAL/keymaster/4.0/service.cpp b/HAL/keymaster/4.1/service.cpp similarity index 88% rename from HAL/keymaster/4.0/service.cpp rename to HAL/keymaster/4.1/service.cpp index db7c9631..9facae9c 100644 --- a/HAL/keymaster/4.0/service.cpp +++ b/HAL/keymaster/4.1/service.cpp @@ -1,6 +1,6 @@ /* ** -** Copyright 2018, The Android Open Source Project +** 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. @@ -23,7 +23,7 @@ int main() { ::android::hardware::configureRpcThreadpool(1, true); - auto keymaster = new ::keymaster::V4_0::JavacardKeymaster4Device(); + auto keymaster = new ::android::hardware::keymaster::V4_1::JavacardKeymaster4Device(); auto status = keymaster->registerAsService(); if (status != android::OK) { diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 8676aaa6..910e0136 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -1,25 +1,28 @@ -// FIXME: your file license if you have one +// Copyright (C) 2017 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. +// cc_binary { - // FIXME: this should only be -impl for a passthrough hal. - // In most cases, to convert this to a binderized implementation, you should: - // - change '-impl' to '-service' here and make it a cc_binary instead of a - // cc_library_shared. - // - add a *.rc file for this module. - // - delete HIDL_FETCH_I* functions. - // - call configureRpcThreadpool and registerAsService on the instance. - // You may also want to append '-impl/-service' with a specific identifier like - // '-vendor' or '-' etc to distinguish it. - // FIXME: this should be 'vendor: true' for modules that will eventually be - // on AOSP. - name: "android.hardware.keymaster@4.0-service.javacard", + name: "android.hardware.keymaster@4.1-service.javacard", defaults: ["hidl_defaults"], relative_install_path: "hw", vendor: true, - init_rc: ["4.0/android.hardware.keymaster@4.0-service.javacard.rc"], + init_rc: ["4.1/android.hardware.keymaster@4.1-service.javacard.rc"], srcs: [ - "4.0/service.cpp", - "4.0/JavacardKeymaster4Device.cpp", + "4.1/service.cpp", + "4.1/JavacardKeymaster4Device.cpp", + "4.1/Operation.cpp", ], local_include_dirs: [ "include", @@ -34,8 +37,6 @@ cc_binary { "libhidlbase", "libkeymaster_messages", "libcn-cbor", - "android.hardware.keymaster@4.0", + "android.hardware.keymaster@4.1", ], - - vintf_fragments: ["4.0/android.hardware.keymaster@4.0-service.javacard.xml"], } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 50f32d52..802bb603 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -15,88 +15,63 @@ ** limitations under the License. */ -#ifndef keymaster_V4_0_JavacardKeymaster4Device_H_ -#define keymaster_V4_0_JavacardKeymaster4Device_H_ +#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ +#define ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ -#include +#include +#include #include +namespace android { +namespace hardware { namespace keymaster { +namespace V4_1 { -namespace V4_0 { - -using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::hardware::keymaster::V4_0::ErrorCode; -using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; -using ::android::hardware::keymaster::V4_0::HardwareAuthToken; -using ::android::hardware::keymaster::V4_0::HmacSharingParameters; -using ::android::hardware::keymaster::V4_0::IKeymasterDevice; -using ::android::hardware::keymaster::V4_0::KeyCharacteristics; -using ::android::hardware::keymaster::V4_0::KeyFormat; -using ::android::hardware::keymaster::V4_0::KeyParameter; -using ::android::hardware::keymaster::V4_0::KeyPurpose; -using ::android::hardware::keymaster::V4_0::SecurityLevel; -using ::android::hardware::keymaster::V4_0::Tag; -using ::android::hardware::keymaster::V4_0::VerificationToken; +using ::android::sp; class JavacardKeymaster4Device : public IKeymasterDevice { public: explicit JavacardKeymaster4Device(); virtual ~JavacardKeymaster4Device(); - + // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; Return getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override; - Return computeSharedHmac(const hidl_vec& params, - computeSharedHmac_cb) override; - Return verifyAuthorization(uint64_t challenge, - const hidl_vec& parametersToVerify, - const HardwareAuthToken& authToken, - verifyAuthorization_cb _hidl_cb) override; - 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 importWrappedKey(const hidl_vec& wrappedKeyData, - const hidl_vec& wrappingKeyBlob, - const hidl_vec& maskingKey, - const hidl_vec& unwrappingParams, - uint64_t passwordSid, uint64_t biometricSid, - importWrappedKey_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 destroyAttestationIds() override; - Return begin(KeyPurpose purpose, const hidl_vec& key, - const hidl_vec& inParams, const HardwareAuthToken& authToken, - begin_cb _hidl_cb) override; - Return update(uint64_t operationHandle, const hidl_vec& inParams, - const hidl_vec& input, const HardwareAuthToken& authToken, - const VerificationToken& verificationToken, update_cb _hidl_cb) override; - Return finish(uint64_t operationHandle, const hidl_vec& inParams, - const hidl_vec& input, const hidl_vec& signature, - const HardwareAuthToken& authToken, - const VerificationToken& verificationToken, finish_cb _hidl_cb) override; - Return abort(uint64_t operationHandle) override; + Return computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) override; + Return verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) override; + Return<::android::hardware::keymaster::V4_0::ErrorCode> addRngEntropy(const hidl_vec& data) override; + Return generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) override; + Return importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) override; + Return importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) override; + Return getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) override; + Return exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, 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<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) override; + Return upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) override; + Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteKey(const hidl_vec& keyBlob) override; + Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteAllKeys() override; + Return<::android::hardware::keymaster::V4_0::ErrorCode> destroyAttestationIds() override; + Return begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) override; + Return update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) override; + Return finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) override; + Return<::android::hardware::keymaster::V4_0::ErrorCode> abort(uint64_t operationHandle) override; + + // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. + Return<::android::hardware::keymaster::V4_1::ErrorCode> deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) override; + Return<::android::hardware::keymaster::V4_1::ErrorCode> earlyBootEnded() override; + Return beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, beginOp_cb _hidl_cb) override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. }; -} // namespace V4_0 +} // namespace V4_1 } // namespace keymaster +} // namespace hardware +} // namespace android -#endif // keymaster_V4_0_JavacardKeymaster4Device_H_ +#endif // ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ diff --git a/HAL/keymaster/include/Operation.h b/HAL/keymaster/include/Operation.h new file mode 100644 index 00000000..6c0cdd55 --- /dev/null +++ b/HAL/keymaster/include/Operation.h @@ -0,0 +1,53 @@ +/* + ** + ** 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. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ +#define ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ + +#include +#include +#include + +namespace android { +namespace hardware { +namespace keymaster { +namespace V4_1 { + + +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +class Operation : public IOperation { + public: + // Methods from ::android::hardware::keymaster::V4_1::IOperation follow. + ::android::hardware::Return getOperationChallenge(getOperationChallenge_cb _hidl_cb) override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. + +}; + +} // namespace V4_1 +} // namespace keymaster +} // namespace hardware +} // namespace android + +#endif /* ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ */ From 875fc9ff93a227c78bac291b75007543d484a9c3 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 29 Mar 2020 04:50:19 +0530 Subject: [PATCH 05/58] Removed unwanted files --- .../4.1/.JavacardKeymaster4Device.cpp.swo | Bin 16384 -> 0 bytes .../4.1/.JavacardKeymaster4Device.cpp.swp | Bin 16384 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo delete mode 100644 HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp diff --git a/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo b/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swo deleted file mode 100644 index d27a6c47d35a42a192926f8e1442f2e601839c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3?T;Hr9mlsVkf)}PZ$RQ zX2<6^<uK*!lp-S+gpsi+(@&py>X`NR9oM%ks}nJ)lW%qv zORJ@|rRv=L=RZ5O=rvuTT?jlWxK|M!>9Tp7T~SO1)VF$Pcw4Et36 zr2S>ONnI+vb7|_SCAP_3mUqK&YJ(=zC}0%mE6`Dm6AOpeKQn(ap6U;rG!ZCNjY7r}Qx z4_pCt@D;EMJ_ZhhL*O9z!y(Ih1H2Ai0IR?ON5K8yUT_b1;h<%G7hDBRz<>wdIshNQ zPr&!U*8m4i&;Z}xZ&_al3@m`7;Qf7;^;hs3xDI{^UItHsCGaqK5d7mKC=1>L&w@*! z3g*Bk!69$}><3SM7+QcM-~f2d1gxz)_IdV_%Gu)=TS^<)ztLi+g^}tq-Txxo9&bxm)4h za85|0s4Jv5mJ#u*EGer0B#)3z(3Ln~!h_~2m9!n@b$Z%-QU(W4Hc$YEO?Jvn???7o zU)0Bn)D%hTiAyqlXl02iI#kfMNwvIGCcGW`tjz*tt;K4b-h>)w$fWZwj)NP7R2Q`m zam}-?2qHyd!8VzDy2AstP*Z1)lHt~KWO~8AzuKWGCAWncD+DKFK^czhpz%?eb3_~V zxl<5lptA;22Rk>XWf}4kV}WFYf;^4IXip<(gY_O2vQ5?S@X_5hJW5b-tjlz%?Y>2c z9R|>Cb}K|2?N1~P>Y6p1BgpAHLy*}2YphqcM+3@ek5XxI^DS#SBGb*Z*m*ARS)nEi zn52rq^4)7RaMN^mm!%YPQFx3zy*0EHO?2AZ^_0%)o;I(k=dA_JXhjybs9jk?ui zd!GPqi~2qbn(1)QCS{g^C6abjt132Fkk3+gCrPMRRJ{O1RdIny-WXm#lK~+@-H%)Z zD>U%@)RH}qi_N&90&EtNUyUoC&DN0ZSRP7`dtL=o1)M&kgJ>;&!r@tVtWojXri<%Tj8vGonov z4d3B*6!#^@tsklAWei%_sD; zUtY;hqR68DQEHEV^wTMObzt0=wdRE*7gR<@GALSXf&tl&Zz$3MsFV#d2w>SS^-I z`1U9%l%62xilwC-VH}1?!mfl8vJteY9pKFC8|Co`&*pWkBi^{(ghynsfCyj&nJH9A zu`)x>7AnO`E;eaB@O9;qUG8u!Mx@>&c+&N`OY1&^UtQfUZAykbB?u4jn9CI$%#lbm zlwP8BJ#k%nkI_;pbZooZ?dBZD$6J4ar!;I?FrE#ZQ3KE zt|;oKSlvQ=YYa(FRop}`DH{kyaI_so;An%xRCdK>q0$EG#nI<9z@ z_heOyOU#WOz-+Vh{{L<4lP_Tpt@r=w`+Em_{3GBX_#^iBuYhO4HLwLf3ho5I!M^@g z@N4iK_Uj?|D)<8U1o#{3{WJI-_&In9{0RII`~Z9d=(ag9mr=kdU=%P47zK<1MggOM zQQ&_^fh|I?x87klY>npVjq`*c_s!pv48)9*t#ua1OQPIad@ReD7WUKiA)g0vsBAdq zr1ORX!DFvP5);CX3`KO?(Y`us@}L~fI!>~=cARu~?Ks)?+HoM@oa3BBc(30sN!m~2 zc{{u>!QDH){@8s}Y4{V7u~e+Iz1>x^GBwJW_&ypL8h#hDi-t}*P8O2R!rc=iZns$B zv=}#|((j!WLMmmaqL@cD>Ht=Fi!^O;2@79wTLF@`17GHlXMsS8z(%G8~^|S diff --git a/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp b/HAL/keymaster/4.1/.JavacardKeymaster4Device.cpp.swp deleted file mode 100644 index 5e8ec6bb35e1502b45664da232eb8cfff91c80e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3?~fZt8OJx2wxMY#&>jBY{9yoWGo^u!bIQtUHi#X%mu|2)@ z&ayi`$E{NO3Pcg~AK*n1Z`v1aU+@kI310B7<(CvB{)6&EeNhP{BtrPk{_?N0vv)13 z1as0yj%R0Qp7}mAv-3ROG#0OvE|YWlMFW4IFpRA~^{?H!&pWov45J$`Ulrf&uT|CSC~g(@(r?T8#juVwTxWTW?Q@IeEzg_T zg}$g2&mKr5gX&0viVKct zI-0 zi5rA3uPPhDmgg~b-v48d9E&3PDgg8z30g6ih}{osEId5_M(atl}wYm zwh!Y?vyE3rdemp8nZ8zHnpc+Vi>3)Fwy94$3@@I*#IBo&8I}e)qRjvDG9>h95cGs^ zSGhe@+Ta5B`rHbO$F-J%lT&jXQx;Yq+CO8G-%Zzpy?W%O)?zO6sbsMHgVuYf>Di)WbIiK$3x8GEj68pH zWGYV;(9XOe9nykXdl$9s9k;daN?&*rk`5-0vh95=U#m?Whqq=I|gO1r79cmqIdr)_(HtuE_Hb_TS?g3&vyuH;Toa71ggJiV`=cJ6c+ ztOrc0is^W^Do@vI#iz+!++jXBjONo8zP_A4dq$nR^V07IvOkB@JqAY>7Kp<;T!!0g zfU~L1d?MS7Y~j^sH(>d&N|mwULbyJv6nMPl~x~(n-Mp}^2cd@t$9tIsA1b7?- z1a^h(TrJf$D!VmuwYalWEZ0iwRZ`g@tCjLvsaC3#@$DihmY*S;rSe*iFb+d}!ftpz zWFzQP4S+K{GRo!w4#f@ZN%o}Oga>4}f^cC3nJZRFsX9k46sx6bE;MP^byVX%`*xRO zV?gLdc8cw zlx(xS@LL76r_>AzTcy?Ya&`U865f7KZhJ;_Nr(1{Xh@3oDfU1Q-`uDi~;!!&G*|VxCk6sx8#v)Wv$}LBio?BIRP=4$D>yZB4wMBY4Uy*AduB=GAV=k$Rt`94=eeo=_!U15l87lt2jo9{e z#K9{5e>@B}5tkySzXponQE)GK2QmE5!4JVcxDGCZO>hbP5%Kyj!B2q=R9sKNb?`}0 zL)^Xs?jSC|4gLjQ0WX0~Py!p^Gl8Lx|(K8;14BYDcN}Y>mv$oWx@vk7Gy0&Ctjz1(gU~xkTC;d^P;yV4q zc@;r~iVnk-5a+|fB-n6~5(UFKY(fIAoSu+4^u)lAG?NqKXj#n+E*!yS#uk~jHuyCllw_i}!Sz(nq)s+N VW^c2H*|4)L?Hm#lO3v|p`#-du(mMbE From 5d896addad8c69dd895de13f554d2167155aa7a8 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 29 Mar 2020 04:53:41 +0530 Subject: [PATCH 06/58] Corrected the year of Copyright --- HAL/keymaster/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 910e0136..da1ea3b6 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 The Android Open Source Project +// Copyright (C) 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. From 95c6269ad5381ace2398cfb764ed9d9605aa0caf Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 29 Mar 2020 04:58:02 +0530 Subject: [PATCH 07/58] Renamed 4.0 to 4.1 in service.cpp --- HAL/keymaster/4.1/service.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HAL/keymaster/4.1/service.cpp b/HAL/keymaster/4.1/service.cpp index 9facae9c..60123b5c 100644 --- a/HAL/keymaster/4.1/service.cpp +++ b/HAL/keymaster/4.1/service.cpp @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include @@ -27,7 +27,7 @@ int main() { auto status = keymaster->registerAsService(); if (status != android::OK) { - LOG(FATAL) << "Could not register service for Keymaster 4.0 (" << status << ")"; + LOG(FATAL) << "Could not register service for Keymaster 4.1 (" << status << ")"; return -1; } From 544dfd1dec6e319f05582b1d43bfef3b25b940c7 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 29 Mar 2020 23:11:18 +0100 Subject: [PATCH 08/58] Added CboreConvert class --- HAL/keymaster/4.1/CborConverter.cpp | 103 ++++++++++++ .../4.1/JavacardKeymaster4Device.cpp | 2 +- HAL/keymaster/Android.bp | 1 + HAL/keymaster/include/CborConverter.h | 148 ++++++++++++++++++ 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 HAL/keymaster/4.1/CborConverter.cpp create mode 100644 HAL/keymaster/include/CborConverter.h diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp new file mode 100644 index 00000000..91730b28 --- /dev/null +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -0,0 +1,103 @@ +/* + ** + ** 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 +#include "../include/CborConverter.h" + +namespace android { +namespace hardware { +namespace keymaster { +namespace V4_1 { + +CborConverter::CborConverter() { +//TODO +} + +CborConverter::~CborConverter() { +//TODO +} + +uint32_t CborConverter::decodeHardwareAuthToken(const uint8_t *buf, size_t len, + std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { + //TODO +} + +uint32_t CborConverter::encodeHardwareAuthToken( + const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::decodeHmacSharingParameters(const uint8_t *buf, size_t len, + std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms) { + //TODO +} + +uint32_t CborConverter::encodeHmacSharingParameters( + std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::encodeKeyCharacteristics( + const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics, + uint8_t **buf, size_t *len) { + //TODO +} + +uint32_t CborConverter::decodeKeyCharacteristics(const uint8_t *buf, size_t len, + std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics) { + //TODO +} + +uint32_t CborConverter::encodeKeyParameter( + const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::encodeKeyParameter( + const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::encodeVerificationToken( + const std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::decodeVerificationToken(const uint8_t *buf, size_t len, + std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { + //TODO +} + +uint32_t CborConverter::encodeByteArray(const std::vector &bytes, uint8_t **buf, + size_t *len) { + //TODO +} + +uint32_t CborConverter::decodeByteArray(const uint8_t *buf, const size_t len, + std::vector &bytes) { + //TODO +} + +} // namespace V4_1 +} // namespace keymaster +} // namespace hardware +} // namespace android diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 0f3d0584..899d2982 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -15,7 +15,7 @@ ** limitations under the License. */ -#define LOG_TAG "android.hardware.keymaster@4.0-impl.trusty" +#define LOG_TAG "android.hardware.keymaster@4.1-service.javacard" #include #include diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index da1ea3b6..0cdbdfc1 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -23,6 +23,7 @@ cc_binary { "4.1/service.cpp", "4.1/JavacardKeymaster4Device.cpp", "4.1/Operation.cpp", + "4.1/CborConverter.cpp" ], local_include_dirs: [ "include", diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h new file mode 100644 index 00000000..fb4fbd2a --- /dev/null +++ b/HAL/keymaster/include/CborConverter.h @@ -0,0 +1,148 @@ +/* + ** + ** 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. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H +#define ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H + +namespace android { +namespace hardware { +namespace keymaster { +namespace V4_1 { + +class CborConverter { + public: + CborConverter(); + + virtual ~CborConverter(); + + //Conversion methods + /** + * Converts from Cbor format to array of HmacSharingParameters structures. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] params The parsed array of HmacSharingParameters structure. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeHmacSharingParameters(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params); + + /** + * Converts from array of HmacSharingParameters structures to Cbor format. + * @param[in] params Array of HmacSharingParameters instances to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeHmacSharingParameters(std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, uint8_t **buf, size_t *len); + + /** + * Converts Cbor format to array of VerificationToken structures. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] tokens The parsed array of VerificationToken structures. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeVerificationTokens(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens); + + /** + * Converts from array of VerificationToken structures to Cbor format. + * @param[in] tokens Array of VerificationToken instances to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeVerificationTokens(const std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens, uint8_t **buf, size_t *len); + + /** + * Converts Cbor format to array of KeyParameter structures. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] params The parsed array of KeyParameter structures. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeKeyParameters(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params); + + /** + * Converts from array of KeyParameter structures to Cbor format. + * @param[in] params Array of KeyParameter instances to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeKeyParameters(const std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params, uint8_t **buf, size_t *len); + + /** + * Converts Cbor format to array of HardwareAuthToken structures. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] tokens The parsed HardwareAuthToken structure. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeHardwareAuthTokens(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens); + + /** + * Converts from array of HardwareAuthToken structures to Cbor format. + * @param[in] tokens Array of HardwareAuthToken instances to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeHardwareAuthTokens(const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens, uint8_t **buf, size_t *len); + + /** + * Converts Cbor format to array of keyCharacteristics structures. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] keyCharacteristics The parsed array of keyCharacteristics structures. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeKeyCharacteristics(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics); + + /** + * Converts from array of KeyCharacteristics structures to Cbor format. + * @param[in] keyCharacteristics Array of KeyCharacteristics instances to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeKeyCharacteristics(const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics, uint8_t **buf, size_t *len); + + /** + * Converts Cbor format to vector array. + * @param[in] buf The array of bytes to convert. + * @param[in] len The number of bytes in the array. + * @param[out] bytes The parsed vector array. + * @return 0 if success, or error code if failure. + */ + uint32_t decodeByteArray(const uint8_t *buf, const size_t len, std::vector& bytes); + + /** + * Converts from vector array to Cbor format. + * @param[in] bytes vector array instance to be encoded. + * @param[out] buf Encoded byte array. + * @param[out] len The number of bytes in the encoded array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeByteArray(const std::vector& bytes, uint8_t **buf, size_t *len); + +}; + +} // namespace V4_1 +} // namespace keymaster +} // namespace hardware +} // namespace android + +#endif //ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H From caf2c6494169eaa1847556befc18fff20d7b79a8 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 29 Mar 2020 23:14:21 +0100 Subject: [PATCH 09/58] Removed unnecessary header file --- HAL/keymaster/4.1/CborConverter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 91730b28..8f49ded7 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -16,7 +16,6 @@ */ #include -#include "../include/CborConverter.h" namespace android { namespace hardware { From 6a0551d8a603e8f89a45e6ab7831c38efb742ec1 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 29 Mar 2020 23:20:06 +0100 Subject: [PATCH 10/58] Corrected function names in CboreConverter source file --- HAL/keymaster/4.1/CborConverter.cpp | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 8f49ded7..f3828ebf 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -16,6 +16,7 @@ */ #include +#include "../include/CborConverter.h" namespace android { namespace hardware { @@ -30,25 +31,25 @@ CborConverter::~CborConverter() { //TODO } -uint32_t CborConverter::decodeHardwareAuthToken(const uint8_t *buf, size_t len, - std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { +uint32_t CborConverter::decodeHardwareAuthTokens(const uint8_t *buf, const size_t len, + std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { //TODO } -uint32_t CborConverter::encodeHardwareAuthToken( - const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, uint8_t **buf, - size_t *len) { +uint32_t CborConverter::encodeHardwareAuthTokens( + const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, + uint8_t **buf, size_t *len) { //TODO } -uint32_t CborConverter::decodeHmacSharingParameters(const uint8_t *buf, size_t len, +uint32_t CborConverter::decodeHmacSharingParameters(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms) { //TODO } uint32_t CborConverter::encodeHmacSharingParameters( - std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, uint8_t **buf, - size_t *len) { + std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, + uint8_t **buf, size_t *len) { //TODO } @@ -58,31 +59,30 @@ uint32_t CborConverter::encodeKeyCharacteristics( //TODO } -uint32_t CborConverter::decodeKeyCharacteristics(const uint8_t *buf, size_t len, +uint32_t CborConverter::decodeKeyCharacteristics(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics) { //TODO } -uint32_t CborConverter::encodeKeyParameter( - const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, uint8_t **buf, - size_t *len) { +uint32_t CborConverter::encodeKeyParameters( + const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, + uint8_t **buf, size_t *len) { //TODO } -uint32_t CborConverter::encodeKeyParameter( - const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, uint8_t **buf, - size_t *len) { +uint32_t CborConverter::decodeKeyParameters(const uint8_t *buf, const size_t len, + std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms) { //TODO } -uint32_t CborConverter::encodeVerificationToken( - const std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens, uint8_t **buf, - size_t *len) { +uint32_t CborConverter::encodeVerificationTokens( + const std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens, + uint8_t **buf, size_t *len) { //TODO } -uint32_t CborConverter::decodeVerificationToken(const uint8_t *buf, size_t len, - std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { +uint32_t CborConverter::decodeVerificationTokens(const uint8_t *buf, const size_t len, + std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { //TODO } From 96e08c5d4b0bf2db3bc5fb44fd850c64baee5a8d Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 29 Mar 2020 23:21:15 +0100 Subject: [PATCH 11/58] Removed unnecessary header file --- HAL/keymaster/4.1/CborConverter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index f3828ebf..a9a317e4 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -16,7 +16,6 @@ */ #include -#include "../include/CborConverter.h" namespace android { namespace hardware { From a6c36725038bda25d781b40dea44a9b7d0e0f75b Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Mon, 30 Mar 2020 22:47:39 +0100 Subject: [PATCH 12/58] Remodified CborConverter class methods --- HAL/keymaster/4.1/CborConverter.cpp | 81 ++++++++++----- HAL/keymaster/include/CborConverter.h | 144 ++++++++++++++++---------- 2 files changed, 144 insertions(+), 81 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index a9a317e4..af1f8478 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -30,72 +30,97 @@ CborConverter::~CborConverter() { //TODO } -uint32_t CborConverter::decodeHardwareAuthTokens(const uint8_t *buf, const size_t len, - std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { +uint32_t CborConverter::decodeData(const uint8_t *buf, const size_t len, void **ctx) { //TODO } -uint32_t CborConverter::encodeHardwareAuthTokens( - const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, - uint8_t **buf, size_t *len) { +uint32_t CborConverter::getElement(const void *ctx, const uint32_t index, void **innerCtx) { //TODO } -uint32_t CborConverter::decodeHmacSharingParameters(const uint8_t *buf, const size_t len, - std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms) { +uint32_t CborConverter::getHmacSharingParameters(const void *ctx, + std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms) { //TODO } -uint32_t CborConverter::encodeHmacSharingParameters( - std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, - uint8_t **buf, size_t *len) { +uint32_t CborConverter::getVerificationTokens(const void *ctx, + std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { //TODO } -uint32_t CborConverter::encodeKeyCharacteristics( - const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics, - uint8_t **buf, size_t *len) { +uint32_t CborConverter::getKeyParameters(const void *ctx, + std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms) { //TODO } -uint32_t CborConverter::decodeKeyCharacteristics(const uint8_t *buf, const size_t len, - std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics) { +uint32_t CborConverter::getHardwareAuthTokens(const void *ctx, + std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { //TODO } -uint32_t CborConverter::encodeKeyParameters( - const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, - uint8_t **buf, size_t *len) { +uint32_t CborConverter::getKeyCharacteristics(const void *ctx, + std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics) { + //TODO +} + +uint32_t CborConverter::getByteArray(const void *ctx, std::vector &bytes) { + //TODO +} + +uint32_t CborConverter::getUInt64Array(const void *ctx, std::vector &values) { + //TODO +} + +uint32_t CborConverter::getUInt32Array(const void *ctx, std::vector &values) { //TODO } -uint32_t CborConverter::decodeKeyParameters(const uint8_t *buf, const size_t len, - std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms) { +uint32_t CborConverter::encodeHmacSharingParameters( + const std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, + std::vector &cborData) { //TODO } uint32_t CborConverter::encodeVerificationTokens( const std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens, - uint8_t **buf, size_t *len) { + std::vector &cborData) { + //TODO +} + +uint32_t CborConverter::encodeKeyParameters( + const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, + std::vector &cborData) { + //TODO +} + +uint32_t CborConverter::encodeHardwareAuthTokens( + const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, + std::vector &cborData) { + //TODO +} + +uint32_t CborConverter::encodeKeyCharacteristics( + const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics, + std::vector &cborData) { //TODO } -uint32_t CborConverter::decodeVerificationTokens(const uint8_t *buf, const size_t len, - std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { +uint32_t CborConverter::encodeByteArray(const std::vector &bytes, + std::vector &cborData) { //TODO } -uint32_t CborConverter::encodeByteArray(const std::vector &bytes, uint8_t **buf, - size_t *len) { +uint32_t CborConverter::encodeUInt64Array(std::vector &bytes, + std::vector &cborData) { //TODO } -uint32_t CborConverter::decodeByteArray(const uint8_t *buf, const size_t len, - std::vector &bytes) { +uint32_t CborConverter::encodeUInt32Array(std::vector &bytes, + std::vector &cborData) { //TODO } } // namespace V4_1 } // namespace keymaster } // namespace hardware -} // namespace android +} // namespace android \ No newline at end of file diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index fb4fbd2a..4d702f02 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -31,113 +31,151 @@ class CborConverter { //Conversion methods /** - * Converts from Cbor format to array of HmacSharingParameters structures. - * @param[in] buf The array of bytes to convert. + * Decodes the CBOR data and returns a context. This context + * has to be passed to each API for retrieving individual elements. + * @param[in] buf The array of bytes to decode. * @param[in] len The number of bytes in the array. - * @param[out] params The parsed array of HmacSharingParameters structure. + * @param[out] ctx Data structure formed from parsed CBOR data. * @return 0 if success, or error code if failure. */ - uint32_t decodeHmacSharingParameters(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params); + uint32_t decodeData(const uint8_t *buf, const size_t len, void **ctx); - /** - * Converts from array of HmacSharingParameters structures to Cbor format. - * @param[in] params Array of HmacSharingParameters instances to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeHmacSharingParameters(std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, uint8_t **buf, size_t *len); + /** + * Get an element at index from the main context. + * @param[in] ctx Data structure pointer returned from @ref decodeData(const uint8_t, const size_t, void**). + * @param[in] index The position where to retrieve the element from. + * @param[out] innerCtx Data structure corresponding to the element at index. + * @return 0 if success, or error code if failure. + */ + uint32_t getElement(const void *ctx, const uint32_t index, void **innerCtx); /** - * Converts Cbor format to array of VerificationToken structures. - * @param[in] buf The array of bytes to convert. - * @param[in] len The number of bytes in the array. - * @param[out] tokens The parsed array of VerificationToken structures. + * Retrieves the array of HmacSharingParameters. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] params The array of HmacSharingParameters. + * @return 0 if success, or error code if failure. + */ + uint32_t getHmacSharingParameters(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params); + + /** + * Converts from array of HmacSharingParameters structures to Cbor format. + * @param[in] params Array of HmacSharingParameters instances to be encoded. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t decodeVerificationTokens(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens); + uint32_t encodeHmacSharingParameters(const std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, std::vector& cborData); + + /** + * Retrieves the array of VerificationTokens. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] tokens The array of VerificationToken structures. + * @return 0 if success, or error code if failure. + */ + uint32_t getVerificationTokens(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens); /** * Converts from array of VerificationToken structures to Cbor format. * @param[in] tokens Array of VerificationToken instances to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t encodeVerificationTokens(const std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens, uint8_t **buf, size_t *len); + uint32_t encodeVerificationTokens(const std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens, std::vector& cborData); /** - * Converts Cbor format to array of KeyParameter structures. - * @param[in] buf The array of bytes to convert. - * @param[in] len The number of bytes in the array. - * @param[out] params The parsed array of KeyParameter structures. + * Retrieves the array of KeyParameter structures. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] params The array of KeyParameter structures. * @return 0 if success, or error code if failure. */ - uint32_t decodeKeyParameters(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params); + uint32_t getKeyParameters(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params); /** * Converts from array of KeyParameter structures to Cbor format. * @param[in] params Array of KeyParameter instances to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t encodeKeyParameters(const std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params, uint8_t **buf, size_t *len); + uint32_t encodeKeyParameters(const std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params, std::vector& cborData); /** - * Converts Cbor format to array of HardwareAuthToken structures. - * @param[in] buf The array of bytes to convert. - * @param[in] len The number of bytes in the array. - * @param[out] tokens The parsed HardwareAuthToken structure. + * Retrieves the array of HardwareAuthToken structures. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] tokens The array of HardwareAuthToken structures. * @return 0 if success, or error code if failure. */ - uint32_t decodeHardwareAuthTokens(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens); + uint32_t getHardwareAuthTokens(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens); /** * Converts from array of HardwareAuthToken structures to Cbor format. * @param[in] tokens Array of HardwareAuthToken instances to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t encodeHardwareAuthTokens(const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens, uint8_t **buf, size_t *len); + uint32_t encodeHardwareAuthTokens(const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens, std::vector& cborData); /** - * Converts Cbor format to array of keyCharacteristics structures. - * @param[in] buf The array of bytes to convert. - * @param[in] len The number of bytes in the array. - * @param[out] keyCharacteristics The parsed array of keyCharacteristics structures. + * Retrieves the array of keyCharacteristics structures. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] keyCharacteristics The array of keyCharacteristics structures. * @return 0 if success, or error code if failure. */ - uint32_t decodeKeyCharacteristics(const uint8_t *buf, const size_t len, std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics); + uint32_t getKeyCharacteristics(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics); /** * Converts from array of KeyCharacteristics structures to Cbor format. * @param[in] keyCharacteristics Array of KeyCharacteristics instances to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t encodeKeyCharacteristics(const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics, uint8_t **buf, size_t *len); + uint32_t encodeKeyCharacteristics(const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics, std::vector& cborData); /** - * Converts Cbor format to vector array. - * @param[in] buf The array of bytes to convert. - * @param[in] len The number of bytes in the array. - * @param[out] bytes The parsed vector array. + * Retrieves byte array. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] bytes The parsed byte array. * @return 0 if success, or error code if failure. */ - uint32_t decodeByteArray(const uint8_t *buf, const size_t len, std::vector& bytes); + uint32_t getByteArray(const void *ctx, std::vector& bytes); /** * Converts from vector array to Cbor format. - * @param[in] bytes vector array instance to be encoded. - * @param[out] buf Encoded byte array. - * @param[out] len The number of bytes in the encoded array. + * @param[in] bytes Byte array instance to be encoded. + * @param[out] cborData Encoded byte array. * @return 0 if success, or error code if failure. */ - uint32_t encodeByteArray(const std::vector& bytes, uint8_t **buf, size_t *len); + uint32_t encodeByteArray(const std::vector& bytes, std::vector& cborData); + /** + * Retrieves uint64_t array. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] values The parsed uint64_t array. + * @return 0 if success, or error code if failure. + */ + uint32_t getUInt64Array(const void *ctx, std::vector& values); + + /** + * Retrieves uint32_t array. + * @param[in] ctx Data structure context corresponding to this element. + * @param[out] values The parsed uint32_t array. + * @return 0 if success, or error code if failure. + */ + uint32_t getUInt32Array(const void *ctx, std::vector& values); + + /** + * Converts from uint64_t array to Cbor format. + * @param bytes uint64_t array to be encoded. + * @param cborData Encoded byte array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeUInt64Array(std::vector &bytes, std::vector& cborData); + + /** + * Converts from uint32_t array to Cbor format. + * @param bytes uint64_t array to be encoded. + * @param cborData Encoded byte array. + * @return 0 if success, or error code if failure. + */ + uint32_t encodeUInt32Array(std::vector &bytes, std::vector& cborData); }; } // namespace V4_1 From 437f9c7dd65eb71d2b7c85eef34d4cfd5ace39c8 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 14 Apr 2020 14:51:20 +0100 Subject: [PATCH 13/58] Removed Operation class --- HAL/keymaster/4.1/Operation.cpp | 38 ---------------------- HAL/keymaster/include/Operation.h | 53 ------------------------------- 2 files changed, 91 deletions(-) delete mode 100644 HAL/keymaster/4.1/Operation.cpp delete mode 100644 HAL/keymaster/include/Operation.h diff --git a/HAL/keymaster/4.1/Operation.cpp b/HAL/keymaster/4.1/Operation.cpp deleted file mode 100644 index 14b6a473..00000000 --- a/HAL/keymaster/4.1/Operation.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - ** - ** 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 -#define UNUSED(a) a=a - -namespace android { -namespace hardware { -namespace keymaster { -namespace V4_1 { - -// Methods from ::android::hardware::keymaster::V4_1::IOperation follow. -::android::hardware::Return Operation::getOperationChallenge(getOperationChallenge_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); - return Void(); -} - - -} // namespace V4_1 -} // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/HAL/keymaster/include/Operation.h b/HAL/keymaster/include/Operation.h deleted file mode 100644 index 6c0cdd55..00000000 --- a/HAL/keymaster/include/Operation.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - ** - ** 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. - */ - -#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ -#define ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ - -#include -#include -#include - -namespace android { -namespace hardware { -namespace keymaster { -namespace V4_1 { - - -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::sp; - -class Operation : public IOperation { - public: - // Methods from ::android::hardware::keymaster::V4_1::IOperation follow. - ::android::hardware::Return getOperationChallenge(getOperationChallenge_cb _hidl_cb) override; - - // Methods from ::android::hidl::base::V1_0::IBase follow. - -}; - -} // namespace V4_1 -} // namespace keymaster -} // namespace hardware -} // namespace android - -#endif /* ANDROID_HARDWARE_KEYMASTER_V4_1_OPERATION_H_ */ From 7cd28467889daf7a5213269bc1c71dc4afad4af7 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 14 Apr 2020 14:52:17 +0100 Subject: [PATCH 14/58] Removed Operation.cpp file from Android.bp --- HAL/keymaster/Android.bp | 1 - 1 file changed, 1 deletion(-) diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 0cdbdfc1..afee7596 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -22,7 +22,6 @@ cc_binary { srcs: [ "4.1/service.cpp", "4.1/JavacardKeymaster4Device.cpp", - "4.1/Operation.cpp", "4.1/CborConverter.cpp" ], local_include_dirs: [ From 66e41573f3440def26e747139d39053d9e778f01 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 14 Apr 2020 14:53:53 +0100 Subject: [PATCH 15/58] Removed dependency on deleted Operation class --- .../include/JavacardKeymaster4Device.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 802bb603..dca82b21 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -21,6 +21,7 @@ #include #include #include +#include "CborConverter.h" namespace android { namespace hardware { @@ -63,10 +64,23 @@ class JavacardKeymaster4Device : public IKeymasterDevice { // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. Return<::android::hardware::keymaster::V4_1::ErrorCode> deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) override; Return<::android::hardware::keymaster::V4_1::ErrorCode> earlyBootEnded() override; - Return beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, beginOp_cb _hidl_cb) override; + Return beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, + const hidl_vec& keyBlob, + const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, + const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, + beginOp_cb _hidl_cb) override { + return super::begin( + purpose, keyBlob, inParams, authToken, + [&](auto hidl_err, auto hidl_params, auto hidl_handle) { + _hidl_cb(static_cast<::android::hardware::keymaster::V4_1::ErrorCode>(hidl_err), + hidl_params, + new ::android::hardware::keymaster::V4_1::support::Operation(hidl_handle)); + }); - // Methods from ::android::hidl::base::V1_0::IBase follow. + } +protected: + CborConverter cborConverter_; }; } // namespace V4_1 From c8e5fcab9a05b0d5bb9e200de7bf0eb3d45a0b19 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 14 Apr 2020 14:54:56 +0100 Subject: [PATCH 16/58] Modified CborConverter class --- HAL/keymaster/4.1/CborConverter.cpp | 272 ++++++++++++----------- HAL/keymaster/include/CborConverter.h | 304 ++++++++++---------------- 2 files changed, 269 insertions(+), 307 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index af1f8478..e1033101 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -1,126 +1,150 @@ -/* - ** - ** 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 - -namespace android { -namespace hardware { -namespace keymaster { -namespace V4_1 { - -CborConverter::CborConverter() { -//TODO -} - -CborConverter::~CborConverter() { -//TODO -} - -uint32_t CborConverter::decodeData(const uint8_t *buf, const size_t len, void **ctx) { - //TODO -} - -uint32_t CborConverter::getElement(const void *ctx, const uint32_t index, void **innerCtx) { - //TODO -} - -uint32_t CborConverter::getHmacSharingParameters(const void *ctx, - std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms) { - //TODO -} - -uint32_t CborConverter::getVerificationTokens(const void *ctx, - std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens) { - //TODO -} - -uint32_t CborConverter::getKeyParameters(const void *ctx, - std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms) { - //TODO -} - -uint32_t CborConverter::getHardwareAuthTokens(const void *ctx, - std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens) { - //TODO -} - -uint32_t CborConverter::getKeyCharacteristics(const void *ctx, - std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics) { - //TODO -} - -uint32_t CborConverter::getByteArray(const void *ctx, std::vector &bytes) { - //TODO -} - -uint32_t CborConverter::getUInt64Array(const void *ctx, std::vector &values) { - //TODO -} - -uint32_t CborConverter::getUInt32Array(const void *ctx, std::vector &values) { - //TODO -} - -uint32_t CborConverter::encodeHmacSharingParameters( - const std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters> ¶ms, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeVerificationTokens( - const std::vector<::android::hardware::keymaster::V4_0::VerificationToken> &tokens, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeKeyParameters( - const std::vector<::android::hardware::keymaster::V4_0::KeyParameter> ¶ms, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeHardwareAuthTokens( - const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken> &tokens, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeKeyCharacteristics( - const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics> &keyCharacteristics, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeByteArray(const std::vector &bytes, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeUInt64Array(std::vector &bytes, - std::vector &cborData) { - //TODO -} - -uint32_t CborConverter::encodeUInt32Array(std::vector &bytes, - std::vector &cborData) { - //TODO +#pragma +#include +#include +#include +#include +#include "CborConverter.h" +using namespace cppbor; + +HardwareAuthenticatorType convertToHardwareAuthenticatorType(uint64_t val) { + switch (static_cast(val)) { + case HardwareAuthenticatorType::NONE: + return HardwareAuthenticatorType::NONE; + case HardwareAuthenticatorType::PASSWORD: + return HardwareAuthenticatorType::PASSWORD; + case HardwareAuthenticatorType::FINGERPRINT: + return HardwareAuthenticatorType::FINGERPRINT; + case HardwareAuthenticatorType::ANY: + return HardwareAuthenticatorType::ANY; + } +} + +bool convertToTag(uint64_t val, TAG& tag) { + switch (static_cast(val)) { + case TAG::ABC: + tag = TAG::ABC; + break; + case TAG::DEF: + tag = TAG::DEF; + break; + case TAG::GHI: + tag = TAG::GHI; + break; + default: + return false; + } + return true; +} + +bool getTagValue(TAG& tag, KeyParameter& keyParam, uint64_t& value) { + return false; +} + +bool CborConverter::getKeyparameter(const std::pair&, + const std::unique_ptr&> pair, KeyParameter& keyParam) { + bool ret = false; + KeyParameter::IntegerParams p; + uint64_t value; + //TAG will be always uint32_t + if (!getUint64(pair.first, 0, value)) { + return ret; + } + if (!convertToTag(value, keyParam.tag)) return false; + + if (MajorType::UINT == getType(pair.second)) { + if (!getUint64(pair.second, 0, value)) { + return ret; + } + /* TODO*/ + //Convert value to corresponding enum and assign to keyParam.f + } + else if (MajorType::BSTR == getType(pair.second)) { + if (!getBinaryArray(pair.second, 0, keyParam.blob)) { + return ret; + } + } + else { + return ret; + } +} + +ParseResult CborConverter::decodeData(const std::vector cborData) { + const uint8_t* pos; + std::unique_ptr item; + std::string message; + return parse(cborData); +} + +bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { + bool ret = false; + const std::unique_ptr& strItem = getItemAtPos(item, pos); + if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + return ret; + + const Bstr* bstr = strItem.get()->asBstr(); + for (auto bchar : bstr->value()) { + value.push_back(bchar); + } + ret = true; + return ret; +} + + +bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { + std::vector nonce; + bool ret = false; + //Seed + if (!getBinaryArray(item, pos, params.seed)) + return ret; + //nonce + if (!getBinaryArray(item, pos+1, nonce)) + return ret; + std::copy(nonce.begin(), nonce.end(), params.nonce); + ret = true; + return ret; +} + +bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& token) { + bool ret = false; + //challenge + if (!getUint64(item, pos, token.challenge)) + return ret; + //userId + if (!getUint64(item, pos+1, token.userId)) + return ret; + //AuthenticatorId + if (!getUint64(item, pos+2, token.authenticatorId)) + return ret; + //AuthType + uint64_t authType; + if (!getUint64(item, pos+3, authType)) + return ret; + token.authType = convertToHardwareAuthenticatorType(authType); + //Timestamp + if (!getUint64(item, pos+4, token.timestamp)) + return ret; + if (!getBinaryArray(item, pos + 5, token.mac)) + return ret; + ret = true; + return ret; +} + +bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams) { + bool ret = false; + const std::unique_ptr& mapItem = getItemAtPos(item, pos); + if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) + return ret; + + const Map* map = mapItem.get()->asMap(); + size_t mapSize = map->size(); + for (int i = 0; i < mapSize; i++) { + KeyParameter param; + if (!getKeyparameter((*map)[i], param)) { + return ret; + } + keyParams.push_back(param); + } + ret = true; + return ret; } -} // namespace V4_1 -} // namespace keymaster -} // namespace hardware -} // namespace android \ No newline at end of file diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 4d702f02..20084d7e 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -1,186 +1,124 @@ -/* - ** - ** 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. - */ - -#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H -#define ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H - -namespace android { -namespace hardware { -namespace keymaster { -namespace V4_1 { - -class CborConverter { - public: - CborConverter(); - - virtual ~CborConverter(); - - //Conversion methods - /** - * Decodes the CBOR data and returns a context. This context - * has to be passed to each API for retrieving individual elements. - * @param[in] buf The array of bytes to decode. - * @param[in] len The number of bytes in the array. - * @param[out] ctx Data structure formed from parsed CBOR data. - * @return 0 if success, or error code if failure. - */ - uint32_t decodeData(const uint8_t *buf, const size_t len, void **ctx); - - /** - * Get an element at index from the main context. - * @param[in] ctx Data structure pointer returned from @ref decodeData(const uint8_t, const size_t, void**). - * @param[in] index The position where to retrieve the element from. - * @param[out] innerCtx Data structure corresponding to the element at index. - * @return 0 if success, or error code if failure. - */ - uint32_t getElement(const void *ctx, const uint32_t index, void **innerCtx); - - /** - * Retrieves the array of HmacSharingParameters. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] params The array of HmacSharingParameters. - * @return 0 if success, or error code if failure. - */ - uint32_t getHmacSharingParameters(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params); - - /** - * Converts from array of HmacSharingParameters structures to Cbor format. - * @param[in] params Array of HmacSharingParameters instances to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeHmacSharingParameters(const std::vector<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, std::vector& cborData); - - /** - * Retrieves the array of VerificationTokens. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] tokens The array of VerificationToken structures. - * @return 0 if success, or error code if failure. - */ - uint32_t getVerificationTokens(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens); - - /** - * Converts from array of VerificationToken structures to Cbor format. - * @param[in] tokens Array of VerificationToken instances to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeVerificationTokens(const std::vector<::android::hardware::keymaster::V4_0::VerificationToken>& tokens, std::vector& cborData); - - /** - * Retrieves the array of KeyParameter structures. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] params The array of KeyParameter structures. - * @return 0 if success, or error code if failure. - */ - uint32_t getKeyParameters(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params); - - /** - * Converts from array of KeyParameter structures to Cbor format. - * @param[in] params Array of KeyParameter instances to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeKeyParameters(const std::vector<::android::hardware::keymaster::V4_0::KeyParameter>& params, std::vector& cborData); - - /** - * Retrieves the array of HardwareAuthToken structures. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] tokens The array of HardwareAuthToken structures. - * @return 0 if success, or error code if failure. - */ - uint32_t getHardwareAuthTokens(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens); - - /** - * Converts from array of HardwareAuthToken structures to Cbor format. - * @param[in] tokens Array of HardwareAuthToken instances to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeHardwareAuthTokens(const std::vector<::android::hardware::keymaster::V4_0::HardwareAuthToken>& tokens, std::vector& cborData); - - /** - * Retrieves the array of keyCharacteristics structures. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] keyCharacteristics The array of keyCharacteristics structures. - * @return 0 if success, or error code if failure. - */ - uint32_t getKeyCharacteristics(const void *ctx, std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics); - - /** - * Converts from array of KeyCharacteristics structures to Cbor format. - * @param[in] keyCharacteristics Array of KeyCharacteristics instances to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeKeyCharacteristics(const std::vector<::android::hardware::keymaster::V4_0::KeyCharacteristics>& keyCharacteristics, std::vector& cborData); - - /** - * Retrieves byte array. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] bytes The parsed byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t getByteArray(const void *ctx, std::vector& bytes); - - /** - * Converts from vector array to Cbor format. - * @param[in] bytes Byte array instance to be encoded. - * @param[out] cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeByteArray(const std::vector& bytes, std::vector& cborData); - - /** - * Retrieves uint64_t array. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] values The parsed uint64_t array. - * @return 0 if success, or error code if failure. - */ - uint32_t getUInt64Array(const void *ctx, std::vector& values); - - /** - * Retrieves uint32_t array. - * @param[in] ctx Data structure context corresponding to this element. - * @param[out] values The parsed uint32_t array. - * @return 0 if success, or error code if failure. - */ - uint32_t getUInt32Array(const void *ctx, std::vector& values); - - /** - * Converts from uint64_t array to Cbor format. - * @param bytes uint64_t array to be encoded. - * @param cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeUInt64Array(std::vector &bytes, std::vector& cborData); - - /** - * Converts from uint32_t array to Cbor format. - * @param bytes uint64_t array to be encoded. - * @param cborData Encoded byte array. - * @return 0 if success, or error code if failure. - */ - uint32_t encodeUInt32Array(std::vector &bytes, std::vector& cborData); +#pragma +#ifndef __CBOR_CONVERTER_H_ +#define __CBOR_CONVERTER_H_ +#include +#include +#include +#include +#include +#include +#include +#include "cppbor.h" +#include "cppbor_parse.h" +using namespace cppbor; +/* Test Start */ +typedef struct HmacSharingParameters { + std::vector seed; + uint8_t nonce[32]; +}; +enum class HardwareAuthenticatorType { + NONE = 0, + PASSWORD = 1 << 0, + FINGERPRINT = 1 << 1, + ANY = 0xFFFFFFFF }; +typedef struct HardwareAuthToken { + uint64_t challenge; + uint64_t userId; + uint64_t authenticatorId; + HardwareAuthenticatorType authType; + uint64_t timestamp; + std::vector mac; +}; +enum class Algorithm { + RSA = 0, + ECDSA = 1, + DSA = 2 +}; +enum class PaddingMode { + PKCS_1 = 0, + PKCS_5 = 1, + OAEP = 2, +}; +enum class TAG { + ABC = 0, + DEF = 1, + GHI = 2 +}; +typedef struct KeyParameter { + TAG tag; + union IntegerParams { + Algorithm algorithm; + PaddingMode mode; + bool boolValue; + uint32_t u32t; + uint64_t u64t; + }; + IntegerParams f; + std::vector blob; +}; +typedef struct VerificationToken { + uint64_t challenge; + uint64_t timestamp; -} // namespace V4_1 -} // namespace keymaster -} // namespace hardware -} // namespace android +}; +/*Test End*/ +class CborConverter +{ +public: + CborConverter() = default; + ~CborConverter() = default; + + ParseResult decodeData(const std::vector cborData); + + /* Use this function to get both signed and usinged integers.*/ + template + bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); + bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); + bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); + bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams); + + +private: + inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } + bool getKeyparameter(const std::pair&, + const std::unique_ptr&> pair, KeyParameter& keyParam); + inline const std::unique_ptr& getItemAtPos(const std::unique_ptr& item, const uint32_t pos) { + const Array* arr = nullptr; + + if (MajorType::ARRAY != getType(item)) { + return nullptr; + } + arr = item.get()->asArray(); + if (arr->size() < (pos + 1)) { + return nullptr; + } + return (*arr)[pos]; + } +}; -#endif //ANDROID_HARDWARE_KEYMASTER_V4_1_CBORCONVERTER_H +template +bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { + bool ret = false; + const std::unique_ptr& intItem = getItemAtPos(item, pos); + + if ((intItem == nullptr) || + (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || + ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { + return ret; + } + + if (std::is_unsigned::value) { + const Uint* uintVal = intItem.get()->asUint(); + value = uintVal->value(); + } + else { + const Nint* nintVal = intItem.get()->asNint(); + value = nintVal->value(); + } + ret = true; + return ret; //success +} + +#endif \ No newline at end of file From cccc6f4042c961690b553c9a8e054e87b6ce6443 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 15 Apr 2020 16:22:30 +0530 Subject: [PATCH 17/58] Fixed initial phase of compilation errors after modifying CborConverter class --- HAL/keymaster/4.1/CborConverter.cpp | 63 ++++++++---- .../4.1/JavacardKeymaster4Device.cpp | 15 +-- HAL/keymaster/Android.bp | 3 +- HAL/keymaster/include/CborConverter.h | 96 ++++++++----------- .../include/JavacardKeymaster4Device.h | 14 --- 5 files changed, 86 insertions(+), 105 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index e1033101..2e1c9b26 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -1,10 +1,28 @@ -#pragma +/* + ** + ** 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 #include #include #include -#include "CborConverter.h" +#include + using namespace cppbor; +#define UNUSED(A) A = A HardwareAuthenticatorType convertToHardwareAuthenticatorType(uint64_t val) { switch (static_cast(val)) { @@ -19,7 +37,10 @@ HardwareAuthenticatorType convertToHardwareAuthenticatorType(uint64_t val) { } } -bool convertToTag(uint64_t val, TAG& tag) { +bool convertToTag(uint64_t val, Tag& tag) { + UNUSED(tag); + UNUSED(val); +#if 0 switch (static_cast(val)) { case TAG::ABC: tag = TAG::ABC; @@ -34,16 +55,20 @@ bool convertToTag(uint64_t val, TAG& tag) { return false; } return true; +#endif + return false; } -bool getTagValue(TAG& tag, KeyParameter& keyParam, uint64_t& value) { +bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { + UNUSED(value); + UNUSED(keyParam); + UNUSED(tag); return false; } bool CborConverter::getKeyparameter(const std::pair&, const std::unique_ptr&> pair, KeyParameter& keyParam) { bool ret = false; - KeyParameter::IntegerParams p; uint64_t value; //TAG will be always uint32_t if (!getUint64(pair.first, 0, value)) { @@ -59,19 +84,16 @@ bool CborConverter::getKeyparameter(const std::pair& //Convert value to corresponding enum and assign to keyParam.f } else if (MajorType::BSTR == getType(pair.second)) { - if (!getBinaryArray(pair.second, 0, keyParam.blob)) { + std::vector blob; + if (!getBinaryArray(pair.second, 0, blob)) { return ret; } + keyParam.blob.setToExternal(blob.data(), blob.size()); } - else { - return ret; - } + return ret; } ParseResult CborConverter::decodeData(const std::vector cborData) { - const uint8_t* pos; - std::unique_ptr item; - std::string message; return parse(cborData); } @@ -91,21 +113,24 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { - std::vector nonce; + std::vector paramValue; bool ret = false; //Seed - if (!getBinaryArray(item, pos, params.seed)) + if (!getBinaryArray(item, pos, paramValue)) return ret; + params.seed.setToExternal(paramValue.data(), paramValue.size()); + paramValue.clear(); //nonce - if (!getBinaryArray(item, pos+1, nonce)) + if (!getBinaryArray(item, pos+1, paramValue)) return ret; - std::copy(nonce.begin(), nonce.end(), params.nonce); + memcpy(params.nonce.data(), paramValue.data(), paramValue.size()); ret = true; return ret; } bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& token) { bool ret = false; + std::vector mac; //challenge if (!getUint64(item, pos, token.challenge)) return ret; @@ -119,12 +144,14 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons uint64_t authType; if (!getUint64(item, pos+3, authType)) return ret; - token.authType = convertToHardwareAuthenticatorType(authType); + token.authenticatorType = convertToHardwareAuthenticatorType(authType); //Timestamp if (!getUint64(item, pos+4, token.timestamp)) return ret; - if (!getBinaryArray(item, pos + 5, token.mac)) + //MAC + if (!getBinaryArray(item, pos + 5, mac)) return ret; + token.mac.setToExternal(mac.data(), mac.size()); ret = true; return ret; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 899d2982..e8abdca3 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -39,7 +39,7 @@ JavacardKeymaster4Device::~JavacardKeymaster4Device() { // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { - _hidl_cb(SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); + _hidl_cb(::android::hardware::keymaster::V4_0::SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); return Void(); } @@ -220,19 +220,6 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device return ::android::hardware::keymaster::V4_1::ErrorCode {}; } -Return JavacardKeymaster4Device::beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, beginOp_cb _hidl_cb) { - // TODO implement - UNUSED(purpose); - size_t size = keyBlob.size(); - size = inParams.size(); - uint64_t challenge = authToken.challenge; - UNUSED(challenge); - UNUSED(size); - UNUSED(_hidl_cb); - - return Void(); -} - } // namespace V4_1 } // namespace keymaster } // namespace hardware diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index afee7596..9720ea6a 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -15,7 +15,6 @@ cc_binary { name: "android.hardware.keymaster@4.1-service.javacard", - defaults: ["hidl_defaults"], relative_install_path: "hw", vendor: true, init_rc: ["4.1/android.hardware.keymaster@4.1-service.javacard.rc"], @@ -36,7 +35,7 @@ cc_binary { "libhardware", "libhidlbase", "libkeymaster_messages", - "libcn-cbor", + "libcppbor_external", "android.hardware.keymaster@4.1", ], } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 20084d7e..eae9f4e3 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -1,4 +1,20 @@ -#pragma +/* + ** + ** 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. + */ + #ifndef __CBOR_CONVERTER_H_ #define __CBOR_CONVERTER_H_ #include @@ -8,61 +24,27 @@ #include #include #include -#include "cppbor.h" -#include "cppbor_parse.h" +#include +#include +#include + +#define EMPTY(A) *(A*)nullptr + using namespace cppbor; -/* Test Start */ -typedef struct HmacSharingParameters { - std::vector seed; - uint8_t nonce[32]; -}; -enum class HardwareAuthenticatorType { - NONE = 0, - PASSWORD = 1 << 0, - FINGERPRINT = 1 << 1, - ANY = 0xFFFFFFFF -}; -typedef struct HardwareAuthToken { - uint64_t challenge; - uint64_t userId; - uint64_t authenticatorId; - HardwareAuthenticatorType authType; - uint64_t timestamp; - std::vector mac; -}; -enum class Algorithm { - RSA = 0, - ECDSA = 1, - DSA = 2 -}; -enum class PaddingMode { - PKCS_1 = 0, - PKCS_5 = 1, - OAEP = 2, -}; -enum class TAG { - ABC = 0, - DEF = 1, - GHI = 2 -}; -typedef struct KeyParameter { - TAG tag; - union IntegerParams { - Algorithm algorithm; - PaddingMode mode; - bool boolValue; - uint32_t u32t; - uint64_t u64t; - }; - IntegerParams f; - std::vector blob; -}; -typedef struct VerificationToken { - uint64_t challenge; - uint64_t timestamp; -}; -/*Test End*/ +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; +using ::android::hardware::keymaster::V4_0::HardwareAuthToken; +using ::android::hardware::keymaster::V4_0::HmacSharingParameters; +using ::android::hardware::keymaster::V4_0::IKeymasterDevice; +using ::android::hardware::keymaster::V4_0::KeyCharacteristics; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::SecurityLevel; +using ::android::hardware::keymaster::V4_0::Tag; +using ::android::hardware::keymaster::V4_0::VerificationToken; + class CborConverter { public: @@ -88,11 +70,11 @@ class CborConverter const Array* arr = nullptr; if (MajorType::ARRAY != getType(item)) { - return nullptr; + return EMPTY(std::unique_ptr); } arr = item.get()->asArray(); if (arr->size() < (pos + 1)) { - return nullptr; + return EMPTY(std::unique_ptr); } return (*arr)[pos]; } @@ -121,4 +103,4 @@ bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t return ret; //success } -#endif \ No newline at end of file +#endif diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index dca82b21..f8e54856 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -64,20 +64,6 @@ class JavacardKeymaster4Device : public IKeymasterDevice { // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. Return<::android::hardware::keymaster::V4_1::ErrorCode> deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) override; Return<::android::hardware::keymaster::V4_1::ErrorCode> earlyBootEnded() override; - Return beginOp(::android::hardware::keymaster::V4_0::KeyPurpose purpose, - const hidl_vec& keyBlob, - const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, - const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, - beginOp_cb _hidl_cb) override { - return super::begin( - purpose, keyBlob, inParams, authToken, - [&](auto hidl_err, auto hidl_params, auto hidl_handle) { - _hidl_cb(static_cast<::android::hardware::keymaster::V4_1::ErrorCode>(hidl_err), - hidl_params, - new ::android::hardware::keymaster::V4_1::support::Operation(hidl_handle)); - }); - - } protected: CborConverter cborConverter_; From c85f8ccdbec93cb72dd3e21e39b5aac28a572b27 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Wed, 15 Apr 2020 20:35:49 +0100 Subject: [PATCH 18/58] Integrated getHmacParameters and computeHmacParameters --- HAL/keymaster/4.1/CborConverter.cpp | 34 ++++++----- .../4.1/JavacardKeymaster4Device.cpp | 57 +++++++++++++++---- HAL/keymaster/include/CborConverter.h | 1 + 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 2e1c9b26..7b22b550 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -24,17 +24,15 @@ using namespace cppbor; #define UNUSED(A) A = A -HardwareAuthenticatorType convertToHardwareAuthenticatorType(uint64_t val) { - switch (static_cast(val)) { - case HardwareAuthenticatorType::NONE: - return HardwareAuthenticatorType::NONE; - case HardwareAuthenticatorType::PASSWORD: - return HardwareAuthenticatorType::PASSWORD; - case HardwareAuthenticatorType::FINGERPRINT: - return HardwareAuthenticatorType::FINGERPRINT; - case HardwareAuthenticatorType::ANY: - return HardwareAuthenticatorType::ANY; - } +namespace { +template +inline T legacyEnumConversion(const unint64_t val) { + return static_cast(val); +} + +} +ErrorCode convertToErrorcode(uint64_t val) { + } bool convertToTag(uint64_t val, Tag& tag) { @@ -144,12 +142,12 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons uint64_t authType; if (!getUint64(item, pos+3, authType)) return ret; - token.authenticatorType = convertToHardwareAuthenticatorType(authType); + token.authenticatorType = legacyEnumConversion(authType); //Timestamp if (!getUint64(item, pos+4, token.timestamp)) return ret; //MAC - if (!getBinaryArray(item, pos + 5, mac)) + if (!getBinaryArray(item, pos+5, mac)) return ret; token.mac.setToExternal(mac.data(), mac.size()); ret = true; @@ -175,3 +173,13 @@ bool CborConverter::getKeyParameters(const std::unique_ptr& item, const ui return ret; } +bool CborConverter::getErrorCode(const std::unique_ptr& item, const uint32_t pos, ErrorCode& errorCode) { + bool ret = false; + uint64_t errorVal; + if (!getUint64(item, pos, errorVal)) + return ret; + errorCode = legacyEnumConversion(errorVal); + ret = true; + return ret; +} + diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index e8abdca3..afaa4d45 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -16,22 +16,27 @@ */ #define LOG_TAG "android.hardware.keymaster@4.1-service.javacard" - +#include +#include +#include #include #include #include #include +#include "../include/JavacardKeymaster4Device.h" -/* TODO Remove below UNUSED */ -#define UNUSED(a) a=a +#define UNUSED(a) a=a /* TODO Remove UNUSED. Added temporarily to solve compilation errors. */ +#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" +#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" namespace android { namespace hardware { namespace keymaster { namespace V4_1 { -JavacardKeymaster4Device::JavacardKeymaster4Device() { - // TODO +JavacardKeymaster4Device::JavacardKeymaster4Device() + : cborConverter_(new CborConverter()) { + } JavacardKeymaster4Device::~JavacardKeymaster4Device() { @@ -39,21 +44,49 @@ JavacardKeymaster4Device::~JavacardKeymaster4Device() { // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { - _hidl_cb(::android::hardware::keymaster::V4_0::SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); + _hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); return Void(); } Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); + vec cborData; + CborConverter cc; + ::android::hardware::keymaster::V4_0::HmacSharingParameters hmacSharingParameters; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = 0; + + // TODO Call OMAPI layer and get the Cbor format data. + + auto ctx = cc.decodeData(cborData); + if (ctx != null) { + cc.getErrorCode(ctx, 0, errorCode); //Error Code + cc.getHmacSharingParameters(ctx, 1, hmacSharingParameters); //HmacSharingParameters. + _hidl_cb(errorCode, hmacSharingParameters); + } return Void(); } Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { - // TODO implement - size_t size = params.size(); - UNUSED(size); - UNUSED(_hidl_cb); + Array array; + CborConverter cc; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = 0; + for(size_t i = 0; i < params.size(); ++i) { + array.add(params[i].seed); + array.add(params[i].nonce); + } + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + auto ctx = cc.decodeData(cborOutData); /* TODO Is this separate API required */ + if (ctx != null) { + std::vector bstr; + hidl_vec sharingCheck; + cc.getErrorCode(ctx, 0, errorCode); //Error Code + cc.getBinaryArray(ctx, 1, bstr); + sharingCheck.setToExternal(bstr.data(), bstr.size()); + _hidl_cb(errorCode, sharingCheck); + } return Void(); } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index eae9f4e3..81eb5eaa 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -60,6 +60,7 @@ class CborConverter bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams); + bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, ErrorCode& errorCode); private: From fdf170106cc91ab38013a9a16320548111bc52f9 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Fri, 17 Apr 2020 14:56:19 +0530 Subject: [PATCH 19/58] Implemented getHamcSharingParameters, computeSharedHmac and verifyAuthorization APIs --- HAL/keymaster/4.1/CborConverter.cpp | 150 +++++++++++++----- .../4.1/JavacardKeymaster4Device.cpp | 84 ++++++---- HAL/keymaster/include/CborConverter.h | 8 +- 3 files changed, 170 insertions(+), 72 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 7b22b550..ccab26fc 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -19,44 +19,14 @@ #include #include #include +#include #include using namespace cppbor; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::TagType; #define UNUSED(A) A = A -namespace { -template -inline T legacyEnumConversion(const unint64_t val) { - return static_cast(val); -} - -} -ErrorCode convertToErrorcode(uint64_t val) { - -} - -bool convertToTag(uint64_t val, Tag& tag) { - UNUSED(tag); - UNUSED(val); -#if 0 - switch (static_cast(val)) { - case TAG::ABC: - tag = TAG::ABC; - break; - case TAG::DEF: - tag = TAG::DEF; - break; - case TAG::GHI: - tag = TAG::GHI; - break; - default: - return false; - } - return true; -#endif - return false; -} - bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { UNUSED(value); UNUSED(keyParam); @@ -64,6 +34,41 @@ bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { return false; } +bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { + Map map; + for(size_t i = 0; i < keyParams.size(); i++) { + KeyParameter param = keyParams[i]; + TagType tagType = static_cast(param.tag & (0xF << 28)); + switch(tagType) { + case TagType::ENUM: + case TagType::ENUM_REP: + case TagType::UINT: + case TagType::UINT_REP: + map.add(static_cast(param.tag), param.f.integer); + break; + case TagType::ULONG: + case TagType::ULONG_REP: + map.add(static_cast(param.tag), param.f.longInteger); + break; + case TagType::DATE: + map.add(static_cast(param.tag), param.f.dateTime); + break; + case TagType::BOOL: + map.add(static_cast(param.tag), param.f.boolValue); + break; + case TagType::BIGNUM: + case TagType::BYTES: + map.add(static_cast(param.tag), (std::vector(param.blob))); + break; + default: + /* Invalid skip */ + break; + } + } + array.add(std::move(map)); + return true; +} + bool CborConverter::getKeyparameter(const std::pair&, const std::unique_ptr&> pair, KeyParameter& keyParam) { bool ret = false; @@ -72,21 +77,38 @@ bool CborConverter::getKeyparameter(const std::pair& if (!getUint64(pair.first, 0, value)) { return ret; } - if (!convertToTag(value, keyParam.tag)) return false; + keyParam.tag = static_cast(value); if (MajorType::UINT == getType(pair.second)) { - if (!getUint64(pair.second, 0, value)) { - return ret; + TagType tagType = static_cast(keyParam.tag & (0xF << 28)); + switch(tagType) { + case TagType::ENUM: + case TagType::ENUM_REP: + case TagType::UINT: + case TagType::UINT_REP: + keyParam.f.integer = static_cast(value); + break; + case TagType::ULONG: + case TagType::ULONG_REP: + keyParam.f.longInteger = static_cast(value); + break; + case TagType::DATE: + keyParam.f.dateTime = static_cast(value); + break; + case TagType::BOOL: + keyParam.f.boolValue = static_cast(value); + break; + default: + /* Invalid skip */ + break; } - /* TODO*/ - //Convert value to corresponding enum and assign to keyParam.f } else if (MajorType::BSTR == getType(pair.second)) { - std::vector blob; + std::vector blob; if (!getBinaryArray(pair.second, 0, blob)) { return ret; } - keyParam.blob.setToExternal(blob.data(), blob.size()); + keyParam.blob.setToExternal(blob.data(), blob.size()); } return ret; } @@ -126,6 +148,17 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, return ret; } +bool CborConverter::addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& +authToken) { + array.add(authToken.challenge); + array.add(authToken.userId); + array.add(authToken.authenticatorId); + array.add(static_cast(authToken.authenticatorType)); + array.add(authToken.timestamp); + array.add((std::vector(authToken.mac))); + return true; +} + bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& token) { bool ret = false; std::vector mac; @@ -142,7 +175,7 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons uint64_t authType; if (!getUint64(item, pos+3, authType)) return ret; - token.authenticatorType = legacyEnumConversion(authType); + token.authenticatorType = static_cast(authType); //Timestamp if (!getUint64(item, pos+4, token.timestamp)) return ret; @@ -154,6 +187,39 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons return ret; } +bool CborConverter::getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& +token) { + bool ret = false; + std::vector mac; + //challenge + if (!getUint64(item, pos, token.challenge)) + return ret; + + //timestamp + if (!getUint64(item, pos+1, token.timestamp)) + return ret; + + //List of KeyParameters + std::vector keyParams; + if (!getKeyParameters(item, pos+2, keyParams)) + return ret; + token.parametersVerified.setToExternal(keyParams.data(), keyParams.size()); + + //AuthenticatorId + uint64_t val; + if (!getUint64(item, pos+3, val)) + return ret; + token.securityLevel = static_cast(val); + + //MAC + if (!getBinaryArray(item, pos+4, mac)) + return ret; + token.mac.setToExternal(mac.data(), mac.size()); + ret = true; + return ret; + +} + bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams) { bool ret = false; const std::unique_ptr& mapItem = getItemAtPos(item, pos); @@ -178,7 +244,7 @@ bool CborConverter::getErrorCode(const std::unique_ptr& item, const uint32 uint64_t errorVal; if (!getUint64(item, pos, errorVal)) return ret; - errorCode = legacyEnumConversion(errorVal); + errorCode = static_cast(errorVal); ret = true; return ret; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index afaa4d45..027f8232 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -23,7 +23,9 @@ #include #include #include -#include "../include/JavacardKeymaster4Device.h" +#include +#include +#include #define UNUSED(a) a=a /* TODO Remove UNUSED. Added temporarily to solve compilation errors. */ #define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" @@ -34,8 +36,7 @@ namespace hardware { namespace keymaster { namespace V4_1 { -JavacardKeymaster4Device::JavacardKeymaster4Device() - : cborConverter_(new CborConverter()) { +JavacardKeymaster4Device::JavacardKeymaster4Device() { } @@ -49,55 +50,80 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ } Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { - vec cborData; - CborConverter cc; + std::vector cborData; + const uint8_t* pos; + std::unique_ptr item; + std::string message; ::android::hardware::keymaster::V4_0::HmacSharingParameters hmacSharingParameters; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = 0; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; // TODO Call OMAPI layer and get the Cbor format data. - auto ctx = cc.decodeData(cborData); - if (ctx != null) { - cc.getErrorCode(ctx, 0, errorCode); //Error Code - cc.getHmacSharingParameters(ctx, 1, hmacSharingParameters); //HmacSharingParameters. - _hidl_cb(errorCode, hmacSharingParameters); + std::tie(item, pos, message) = parse(cborData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters); //HmacSharingParameters. } + _hidl_cb(errorCode, hmacSharingParameters); return Void(); } Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { - Array array; - CborConverter cc; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = 0; + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec sharingCheck; + + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + std::vector tempVec; for(size_t i = 0; i < params.size(); ++i) { - array.add(params[i].seed); - array.add(params[i].nonce); + array.add(static_cast>(params[i].seed)); + for(size_t j = 0; i < params[j].nonce.size(); j++) { + tempVec.push_back(params[i].nonce[j]); + } + array.add(tempVec); + tempVec.clear(); } std::vector cborData = array.encode(); // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. std::vector cborOutData; /*Received from OMAPI */ - auto ctx = cc.decodeData(cborOutData); /* TODO Is this separate API required */ - if (ctx != null) { + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { std::vector bstr; - hidl_vec sharingCheck; - cc.getErrorCode(ctx, 0, errorCode); //Error Code - cc.getBinaryArray(ctx, 1, bstr); + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getBinaryArray(item, 1, bstr); sharingCheck.setToExternal(bstr.data(), bstr.size()); - _hidl_cb(errorCode, sharingCheck); } + _hidl_cb(errorCode, sharingCheck); return Void(); } Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = parametersToVerify.size(); - UNUSED(size); - uint64_t challenge = authToken.challenge; - UNUSED(challenge); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::keymaster::V4_0::VerificationToken verificationToken; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, parametersToVerify); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getVerificationToken(item, 1, verificationToken); + } + _hidl_cb(errorCode, verificationToken); return Void(); } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 81eb5eaa..2e4ba890 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define EMPTY(A) *(A*)nullptr @@ -61,7 +62,12 @@ class CborConverter bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams); bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, ErrorCode& errorCode); - + bool addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& + keyParams); +bool addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& +authToken); +bool getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& +token); private: inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } From 47d07c26694aca66c70f5a503a8d6e4f0e731cff Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sat, 18 Apr 2020 03:33:47 +0530 Subject: [PATCH 20/58] Completed conversion from hidl to cbor and cbor back to hidl types. --- HAL/keymaster/4.1/CborConverter.cpp | 97 ++-- .../4.1/JavacardKeymaster4Device.cpp | 447 ++++++++++++++---- HAL/keymaster/include/CborConverter.h | 100 ++-- 3 files changed, 478 insertions(+), 166 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index ccab26fc..7e321766 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -45,32 +45,48 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl case TagType::UINT: case TagType::UINT_REP: map.add(static_cast(param.tag), param.f.integer); - break; + break; case TagType::ULONG: case TagType::ULONG_REP: map.add(static_cast(param.tag), param.f.longInteger); - break; + break; case TagType::DATE: map.add(static_cast(param.tag), param.f.dateTime); - break; + break; case TagType::BOOL: map.add(static_cast(param.tag), param.f.boolValue); - break; + break; case TagType::BIGNUM: case TagType::BYTES: map.add(static_cast(param.tag), (std::vector(param.blob))); break; default: - /* Invalid skip */ - break; + /* Invalid skip */ + break; } } array.add(std::move(map)); return true; } +bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, + ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) { + bool ret = false; + + if (!getKeyParameters(item, pos, keyCharacteristics.softwareEnforced)) { + return ret; + } + + if (!getKeyParameters(item, pos+1, keyCharacteristics.hardwareEnforced)) { + return ret; + } + //success + ret = true; + return ret; +} + bool CborConverter::getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam) { + const std::unique_ptr&> pair, KeyParameter& keyParam) { bool ret = false; uint64_t value; //TAG will be always uint32_t @@ -87,20 +103,20 @@ bool CborConverter::getKeyparameter(const std::pair& case TagType::UINT: case TagType::UINT_REP: keyParam.f.integer = static_cast(value); - break; + break; case TagType::ULONG: case TagType::ULONG_REP: keyParam.f.longInteger = static_cast(value); - break; + break; case TagType::DATE: keyParam.f.dateTime = static_cast(value); - break; + break; case TagType::BOOL: keyParam.f.boolValue = static_cast(value); - break; + break; default: - /* Invalid skip */ - break; + /* Invalid skip */ + break; } } else if (MajorType::BSTR == getType(pair.second)) { @@ -117,6 +133,24 @@ ParseResult CborConverter::decodeData(const std::vector cborData) { return parse(cborData); } +bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, + ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { + bool ret = false; + const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + const Array* arr = arrayItem.get()->asArray(); + size_t arrSize = arr->size(); + for (int i = 0; i < arrSize; i++) { + std::vector innerData; + if (!getBinaryArray(arrayItem, i, innerData)) + return ret; + data[i].setToExternal(innerData.data(), innerData.size()); + } + ret = true; // success + return ret; +} + bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { bool ret = false; const std::unique_ptr& strItem = getItemAtPos(item, pos); @@ -148,8 +182,18 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, return ret; } +bool CborConverter::addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& + verificationToken) { + array.add(verificationToken.challenge); + array.add(verificationToken.timestamp); + addKeyparameters(array, verificationToken.parametersVerified); + array.add(static_cast(verificationToken.securityLevel)); + array.add((std::vector(verificationToken.mac))); + return true; +} + bool CborConverter::addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& -authToken) { + authToken) { array.add(authToken.challenge); array.add(authToken.userId); array.add(authToken.authenticatorId); @@ -188,7 +232,7 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons } bool CborConverter::getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& -token) { + token) { bool ret = false; std::vector mac; //challenge @@ -200,17 +244,15 @@ token) { return ret; //List of KeyParameters - std::vector keyParams; - if (!getKeyParameters(item, pos+2, keyParams)) + if (!getKeyParameters(item, pos+2, token.parametersVerified)) return ret; - token.parametersVerified.setToExternal(keyParams.data(), keyParams.size()); //AuthenticatorId uint64_t val; if (!getUint64(item, pos+3, val)) return ret; token.securityLevel = static_cast(val); - + //MAC if (!getBinaryArray(item, pos+4, mac)) return ret; @@ -220,7 +262,7 @@ token) { } -bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams) { +bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { bool ret = false; const std::unique_ptr& mapItem = getItemAtPos(item, pos); if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) @@ -229,23 +271,12 @@ bool CborConverter::getKeyParameters(const std::unique_ptr& item, const ui const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); for (int i = 0; i < mapSize; i++) { - KeyParameter param; + ::android::hardware::keymaster::V4_0::KeyParameter param; if (!getKeyparameter((*map)[i], param)) { return ret; } - keyParams.push_back(param); + keyParams[i] = std::move(param); } ret = true; return ret; } - -bool CborConverter::getErrorCode(const std::unique_ptr& item, const uint32_t pos, ErrorCode& errorCode) { - bool ret = false; - uint64_t errorVal; - if (!getUint64(item, pos, errorVal)) - return ret; - errorCode = static_cast(errorVal); - ret = true; - return ret; -} - diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 027f8232..b08ecc1b 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -79,11 +79,11 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi std::vector tempVec; for(size_t i = 0; i < params.size(); ++i) { array.add(static_cast>(params[i].seed)); - for(size_t j = 0; i < params[j].nonce.size(); j++) { - tempVec.push_back(params[i].nonce[j]); - } + for(size_t j = 0; i < params[j].nonce.size(); j++) { + tempVec.push_back(params[i].nonce[j]); + } array.add(tempVec); - tempVec.clear(); + tempVec.clear(); } std::vector cborData = array.encode(); @@ -128,155 +128,414 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan } Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { - // TODO implement - size_t size = data.size(); - UNUSED(size); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; + const uint8_t* pos; + cppbor::Array array; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(std::vector(data)); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); - size_t size = keyParams.size(); - UNUSED(size); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + + cborConverter_.addKeyparameters(array, keyParams); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { - // TODO implement - size_t size = keyParams.size(); - size = keyData.size(); - UNUSED(size); - UNUSED(keyFormat); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + + cborConverter_.addKeyparameters(array, keyParams); + array.add(static_cast(keyFormat)); + array.add(std::vector(keyData)); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { - // TODO implement - size_t size = wrappedKeyData.size(); - size = wrappingKeyBlob.size(); - size = maskingKey.size(); - size = unwrappingParams.size(); - UNUSED(size); - UNUSED(passwordSid); - UNUSED(biometricSid); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + + array.add(std::vector(wrappedKeyData)); + array.add(std::vector(wrappingKeyBlob)); + array.add(std::vector(maskingKey)); + cborConverter_.addKeyparameters(array, unwrappingParams); + array.add(passwordSid); + array.add(biometricSid); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); } Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) { - // TODO implement - size_t size = keyBlob.size(); - size = clientId.size(); - size = appData.size(); - UNUSED(size); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + + array.add(std::vector(keyBlob)); + array.add(std::vector(clientId)); + array.add(std::vector(appData)); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics); + } + _hidl_cb(errorCode, keyCharacteristics); return Void(); } Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { - // TODO implement - size_t size = clientId.size(); - size = keyBlob.size(); - size = appData.size(); - UNUSED(size); - UNUSED(keyFormat); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyMaterial; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + array.add(static_cast(keyFormat)); + array.add(std::vector(keyBlob)); + array.add(std::vector(clientId)); + array.add(std::vector(appData)); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyMaterial.setToExternal(bstr.data(), bstr.size()); + } + _hidl_cb(errorCode, keyMaterial); return Void(); } Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) { - // TODO implement - size_t size = attestParams.size(); - size = keyToAttest.size(); - UNUSED(size); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + ::android::hardware::hidl_vec<::android::hardware::hidl_vec> certChain; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyToAttest)); + cborConverter_.addKeyparameters(array, attestParams); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getMultiBinaryArray(item, 1, certChain); + } + _hidl_cb(errorCode, certChain); return Void(); } Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) { - // TODO implement - size_t size = keyBlobToUpgrade.size(); - size = upgradeParams.size(); - UNUSED(size); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec upgradedKeyBlob; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyBlobToUpgrade)); + cborConverter_.addKeyparameters(array, upgradeParams); + std::vector cborData = array.encode(); + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); + } + _hidl_cb(errorCode, upgradedKeyBlob); return Void(); } Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { - // TODO implement - size_t size = keyBlob.size(); - UNUSED(size); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyBlob)); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteAllKeys() { - // TODO implement - return ::android::hardware::keymaster::V4_0::ErrorCode {}; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::destroyAttestationIds() { - // TODO implement - return ::android::hardware::keymaster::V4_0::ErrorCode {}; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) { - // TODO implement - UNUSED(purpose); - size_t size = keyBlob.size(); - size = inParams.size(); - UNUSED(size); - uint64_t challenge = authToken.challenge; - UNUSED(challenge); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; + uint64_t operationHandle = 0; + + /* Convert input data to cbor format */ + array.add(static_cast(purpose)); + array.add(std::vector(keyBlob)); + cborConverter_.addKeyparameters(array, inParams); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getUint64(item, 2, operationHandle); + } + _hidl_cb(errorCode, outParams, operationHandle); return Void(); } Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = inParams.size(); - size = input.size(); - UNUSED(size); - uint64_t challange = verificationToken.challenge; - challange = authToken.challenge; - UNUSED(challange); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; + uint32_t inputConsumed = 0; + hidl_vec output; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getUint64(item, 1, inputConsumed); + cborConverter_.getKeyParameters(item, 2, outParams); + cborConverter_.getBinaryArray(item, 3, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } + _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); } Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = inParams.size(); - size = input.size(); - size = signature.size(); - uint64_t challange = authToken.challenge; - challange = verificationToken.challenge; - UNUSED(challange); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; + hidl_vec output; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + array.add(std::vector(signature)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getBinaryArray(item, 2, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } + _hidl_cb(errorCode, outParams, output); return Void(); } Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::abort(uint64_t operationHandle) { - // TODO implement - UNUSED(operationHandle); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(operationHandle); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode<::android::hardware::keymaster::V4_0::ErrorCode>(item, 0, errorCode); //Errorcode + } + return errorCode; } // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) { - // TODO implement - UNUSED(passwordOnly); - size_t challenge = verificationToken.challenge; - UNUSED(challenge); - return ::android::hardware::keymaster::V4_1::ErrorCode {}; + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(passwordOnly); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::earlyBootEnded() { - // TODO implement - return ::android::hardware::keymaster::V4_1::ErrorCode {}; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + return errorCode; } } // namespace V4_1 diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 2e4ba890..84e86299 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -48,53 +48,75 @@ using ::android::hardware::keymaster::V4_0::VerificationToken; class CborConverter { -public: - CborConverter() = default; - ~CborConverter() = default; - - ParseResult decodeData(const std::vector cborData); - - /* Use this function to get both signed and usinged integers.*/ - template - bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); - bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); - bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); - bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); - bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams); - bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, ErrorCode& errorCode); - bool addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& - keyParams); -bool addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& -authToken); -bool getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& -token); - -private: - inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } - bool getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam); - inline const std::unique_ptr& getItemAtPos(const std::unique_ptr& item, const uint32_t pos) { - const Array* arr = nullptr; - - if (MajorType::ARRAY != getType(item)) { - return EMPTY(std::unique_ptr); - } - arr = item.get()->asArray(); - if (arr->size() < (pos + 1)) { - return EMPTY(std::unique_ptr); + public: + CborConverter() = default; + ~CborConverter() = default; + + ParseResult decodeData(const std::vector cborData); + + /* Use this function to get both signed and usinged integers.*/ + template + bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); + bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); + bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); + bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams); + bool addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& + keyParams); + bool addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& + authToken); + bool getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& + token); + bool getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, + ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics); + bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, + ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data); + bool addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& + verificationToken); + + template) || + (std::is_same_v)>> + inline bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, T& errorCode) { + bool ret = false; + uint64_t errorVal; + if (!getUint64(item, pos, errorVal)) { + return ret; + } + errorCode = static_cast(errorVal); + + ret = true; + return ret; + } + + + + + private: + inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } + bool getKeyparameter(const std::pair&, + const std::unique_ptr&> pair, KeyParameter& keyParam); + inline const std::unique_ptr& getItemAtPos(const std::unique_ptr& item, const uint32_t pos) { + const Array* arr = nullptr; + + if (MajorType::ARRAY != getType(item)) { + return EMPTY(std::unique_ptr); + } + arr = item.get()->asArray(); + if (arr->size() < (pos + 1)) { + return EMPTY(std::unique_ptr); + } + return (*arr)[pos]; } - return (*arr)[pos]; - } }; template bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { bool ret = false; const std::unique_ptr& intItem = getItemAtPos(item, pos); - + if ((intItem == nullptr) || - (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || - ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { + (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || + ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { return ret; } From 1a1ec7c2284f793458b60d498b3ffa7dbba4655b Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 28 Apr 2020 18:33:28 +0530 Subject: [PATCH 21/58] Modified the ordering HmacSharingParameters and KeyCharacaterstics --- HAL/keymaster/4.1/CborConverter.cpp | 20 +++++++++++++++---- .../4.1/JavacardKeymaster4Device.cpp | 13 +++++++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 7e321766..2679697a 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -73,11 +73,15 @@ bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, con ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) { bool ret = false; - if (!getKeyParameters(item, pos, keyCharacteristics.softwareEnforced)) { + const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + + if (!getKeyParameters(arrayItem, 0, keyCharacteristics.softwareEnforced)) { return ret; } - if (!getKeyParameters(item, pos+1, keyCharacteristics.hardwareEnforced)) { + if (!getKeyParameters(arrayItem, 1, keyCharacteristics.hardwareEnforced)) { return ret; } //success @@ -169,13 +173,21 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { std::vector paramValue; bool ret = false; + + //1. Get ArrayItem + //2. First item in the array seed; second item in the array is nonce. + const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + //Seed - if (!getBinaryArray(item, pos, paramValue)) + if (!getBinaryArray(arrayItem, 0, paramValue)) return ret; params.seed.setToExternal(paramValue.data(), paramValue.size()); paramValue.clear(); + //nonce - if (!getBinaryArray(item, pos+1, paramValue)) + if (!getBinaryArray(arrayItem, 1, paramValue)) return ret; memcpy(params.nonce.data(), paramValue.data(), paramValue.size()); ret = true; diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index b08ecc1b..dd8be396 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -77,14 +77,16 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; std::vector tempVec; + cppbor::Array innerArray; for(size_t i = 0; i < params.size(); ++i) { - array.add(static_cast>(params[i].seed)); + innerArray.add(static_cast>(params[i].seed)); for(size_t j = 0; i < params[j].nonce.size(); j++) { tempVec.push_back(params[i].nonce[j]); } - array.add(tempVec); + innerArray.add(tempVec); tempVec.clear(); } + array.add(std::move(innerArray)); std::vector cborData = array.encode(); // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. @@ -166,6 +168,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::har if (item != nullptr) { std::vector bstr; cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ cborConverter_.getBinaryArray(item, 1, bstr); keyBlob.setToExternal(bstr.data(), bstr.size()); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); @@ -193,6 +196,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardw if (item != nullptr) { std::vector bstr; cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ cborConverter_.getBinaryArray(item, 1, bstr); keyBlob.setToExternal(bstr.data(), bstr.size()); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); @@ -215,12 +219,13 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(std::vector(maskingKey)); cborConverter_.addKeyparameters(array, unwrappingParams); array.add(passwordSid); - array.add(biometricSid); + array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. std::vector cborOutData; /*Received from OMAPI */ std::tie(item, pos, message) = parse(cborOutData); if (item != nullptr) { + /* TODO keyBlob is BSTR */ std::vector bstr; cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); @@ -272,6 +277,7 @@ Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster: std::vector cborOutData; /*Received from OMAPI */ std::tie(item, pos, message) = parse(cborOutData); if (item != nullptr) { + /* TODO Keyblobc - BSTR()*/ std::vector bstr; cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); @@ -319,6 +325,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl std::vector cborOutData; /*Received from OMAPI */ std::tie(item, pos, message) = parse(cborOutData); if (item != nullptr) { + /* TODO Keyblob BSTR(ARRAY) */ std::vector bstr; cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); From f0ab72e8778218f1ff8eb2f1fec526c571f0f2c0 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 4 May 2020 22:45:37 +0530 Subject: [PATCH 22/58] Initial implementation of transport library --- .../4.1/JavacardKeymaster4Device.cpp | 49 ++++----- HAL/keymaster/4.1/OmapiTransport.cpp | 57 ++++++++++ HAL/keymaster/4.1/SocketTransport.cpp | 100 ++++++++++++++++++ HAL/keymaster/Android.bp | 58 +++++++++- .../include/JavacardKeymaster4Device.h | 12 ++- HAL/keymaster/include/Transport.h | 62 +++++++++++ HAL/keymaster/include/TransportFactory.h | 63 +++++++++++ 7 files changed, 372 insertions(+), 29 deletions(-) create mode 100644 HAL/keymaster/4.1/OmapiTransport.cpp create mode 100644 HAL/keymaster/4.1/SocketTransport.cpp create mode 100644 HAL/keymaster/include/Transport.h create mode 100644 HAL/keymaster/include/TransportFactory.h diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index dd8be396..2ae12410 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -27,7 +27,6 @@ #include #include -#define UNUSED(a) a=a /* TODO Remove UNUSED. Added temporarily to solve compilation errors. */ #define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" #define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" @@ -36,10 +35,6 @@ namespace hardware { namespace keymaster { namespace V4_1 { -JavacardKeymaster4Device::JavacardKeymaster4Device() { - -} - JavacardKeymaster4Device::~JavacardKeymaster4Device() { } @@ -390,29 +385,35 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device } Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) { - cppbor::Array array; - const uint8_t* pos; - std::unique_ptr item; - std::string message; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; uint64_t operationHandle = 0; - /* Convert input data to cbor format */ - array.add(static_cast(purpose)); - array.add(std::vector(keyBlob)); - cborConverter_.addKeyparameters(array, inParams); - cborConverter_.addHardwareAuthToken(array, authToken); - std::vector cborData = array.encode(); - - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getUint64(item, 2, operationHandle); + if (::android::hardware::keymaster::V4_0::KeyPurpose::ENCRYPT == purpose || + ::android::hardware::keymaster::V4_0::KeyPurpose::VERIFY == purpose) { + /* Public key operations are handled here*/ + } else { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + + /* Convert input data to cbor format */ + array.add(static_cast(purpose)); + array.add(std::vector(keyBlob)); + cborConverter_.addKeyparameters(array, inParams); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); + + // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + + std::vector cborOutData; /*Received from OMAPI */ + std::tie(item, pos, message) = parse(cborOutData); + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getUint64(item, 2, operationHandle); + } } _hidl_cb(errorCode, outParams, operationHandle); return Void(); diff --git a/HAL/keymaster/4.1/OmapiTransport.cpp b/HAL/keymaster/4.1/OmapiTransport.cpp new file mode 100644 index 00000000..30ec5060 --- /dev/null +++ b/HAL/keymaster/4.1/OmapiTransport.cpp @@ -0,0 +1,57 @@ +/* + ** + ** 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 +#include +#include +#include +#include +#include +#include "Transport.h" + +#define PORT 8080 +#define IPADDR "10.9.40.24" +#define UNUSED_V(a) a=a + +namespace se_transport { + +bool OmapiTransport::openConnection(connectionCallback cb) { + cb(true); + return true; +} + +bool OmapiTransport::sendData(const char* inData, const uint32_t inLen, responseCallback cb) { + std::vector test(inData, inData+inLen); + cb(test); + return true; + +} + +bool OmapiTransport::sendData(const char* inData, const uint32_t inLen, std::vector& output) { + std::vector test(inData, inData+inLen); + output = std::move(test); + return true; +} + +bool OmapiTransport::closeConnection() { + return true; +} + +bool OmapiTransport::isConnected() { + return true; +} + +} diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp new file mode 100644 index 00000000..6c23f5bc --- /dev/null +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -0,0 +1,100 @@ +/* + ** + ** 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 +#include +#include +#include +#include "Transport.h" + +/* TODO How to get these two values */ +#define PORT 8080 +#define IPADDR "10.9.40.24" +#define MAX_RECV_BUFFER_SIZE 2048 + +namespace se_transport { + +bool SocketTransport::openConnection(connectionCallback cb) { + struct sockaddr_in serv_addr; + + if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + LOG(ERROR) << "Socket creation failed"; + return false; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + + // Convert IPv4 and IPv6 addresses from text to binary form + if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) + { + LOG(ERROR) << "Invalid address/ Address not supported."; + return false; + } + + if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + LOG(ERROR) << "Connection failed."; + return false; + } + cb(true);// This can be used for Asynchronous calls. + return true; +} + +bool SocketTransport::sendData(const char* data, uint32_t dataSize, responseCallback cb) { + uint8_t buffer[MAX_RECV_BUFFER_SIZE]; + if (0 > send(mSocket, data ,dataSize , 0 )) { + LOG(ERROR) << "Failed to send data over socket."; + return false; + } + ssize_t valRead = read( mSocket , buffer, MAX_RECV_BUFFER_SIZE); + if(0 > valRead) { + LOG(ERROR) << "Failed to read data from socket."; + } + std::vector output(buffer, buffer+valRead); + cb(output); + return true; +} + +bool SocketTransport::sendData(const char* inData, const uint32_t inLen, std::vector& output) { + uint8_t buffer[MAX_RECV_BUFFER_SIZE]; + if (0 > send(mSocket, inData, inLen , 0 )) { + LOG(ERROR) << "Failed to send data over socket."; + return false; + } + ssize_t valRead = read( mSocket , buffer, MAX_RECV_BUFFER_SIZE); + if(0 > valRead) { + LOG(ERROR) << "Failed to read data from socket."; + } + for(size_t i = 0; i < valRead; i++) { + output.push_back(buffer[i]); + } + return true; + +} + +bool SocketTransport::closeConnection() { + close(mSocket); + return true; +} + +bool SocketTransport::isConnected() { + //TODO + return true; +} + +} diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 9720ea6a..d708814f 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -14,9 +14,7 @@ // cc_binary { - name: "android.hardware.keymaster@4.1-service.javacard", - relative_install_path: "hw", - vendor: true, + name: "android.hardware.keymaster@4.1-javacard-service", init_rc: ["4.1/android.hardware.keymaster@4.1-service.javacard.rc"], srcs: [ "4.1/service.cpp", @@ -35,7 +33,59 @@ cc_binary { "libhardware", "libhidlbase", "libkeymaster_messages", - "libcppbor_external", + "libcppbor_external", + "omapi_external", "android.hardware.keymaster@4.1", + "jc_transport", + ], +} + +cc_library { + name: "android.hardware.keymaster@4.1-javacard", + srcs: [ + "4.1/service.cpp", + "4.1/JavacardKeymaster4Device.cpp", + "4.1/CborConverter.cpp", + ], + local_include_dirs: [ + "include", + ], + shared_libs: [ + "liblog", + "libcutils", + "libdl", + "libbase", + "libutils", + "libhardware", + "libhidlbase", + "libkeymaster_messages", + "libcppbor_external", + "omapi_external", + "android.hardware.keymaster@4.1", + "android.hardware.keymaster@4.0", + "jc_transport", + ], +} + + + +cc_library { + name: "jc_transport", + host_supported: true, + vendor_available: true, + + srcs: [ + "4.1/SocketTransport.cpp", + "4.1/OmapiTransport.cpp" + ], + export_include_dirs: [ + "include" + ], + shared_libs: [ + "libbinder", + "libbase", + "liblog", + "libutils", + "libcurl" ], } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index f8e54856..0494890c 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -21,7 +21,9 @@ #include #include #include +#include #include "CborConverter.h" +#include "TransportFactory.h" namespace android { namespace hardware { @@ -38,8 +40,15 @@ using ::android::sp; class JavacardKeymaster4Device : public IKeymasterDevice { public: - explicit JavacardKeymaster4Device(); + JavacardKeymaster4Device() { + if(android::base::GetBoolProperty("ro.kernel.qemu", false)) + pTransportFactory = std::make_unique(true); + else + pTransportFactory = std::make_unique(false); + } + virtual ~JavacardKeymaster4Device(); + // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; Return getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override; @@ -67,6 +76,7 @@ class JavacardKeymaster4Device : public IKeymasterDevice { protected: CborConverter cborConverter_; + std::unique_ptr pTransportFactory; }; } // namespace V4_1 diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h new file mode 100644 index 00000000..b07f2d20 --- /dev/null +++ b/HAL/keymaster/include/Transport.h @@ -0,0 +1,62 @@ +/* + ** + ** 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. + */ +#ifndef __SE_TRANSPORT__ +#define __SE_TRANSPORT__ + +namespace se_transport { + +typedef void (*connectionCallback)(bool connected); +typedef void (*responseCallback)(std::vector output); + +class ITransport { + public: + virtual ~ITransport(){} + virtual bool openConnection(connectionCallback cb) = 0; + virtual bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) = 0; + virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) = 0; + virtual bool closeConnection() = 0; + virtual bool isConnected() = 0; + +}; + +class OmapiTransport : public ITransport { + +public: + + bool openConnection(connectionCallback cb) override; + bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; + virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; + bool closeConnection() override; + bool isConnected() override; + +}; + +class SocketTransport : public ITransport { + +public: + bool openConnection(connectionCallback cb) override; + bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; + virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; + bool closeConnection() override; + bool isConnected() override; +private: + int mSocket; + +}; + +} +#endif /* __SE_TRANSPORT__ */ diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h new file mode 100644 index 00000000..3c631886 --- /dev/null +++ b/HAL/keymaster/include/TransportFactory.h @@ -0,0 +1,63 @@ +/* + ** + ** 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. + */ +#ifndef __SE_TRANSPORT_FACTORY__ +#define __SE_TRANSPORT_FACTORY__ + +#include "Transport.h" + +namespace se_transport { + +class TransportFactory { + public: + /*TransportFactory(bool isDevice) : mTransport( isDevice ? std::unique_ptr(new OmapiTransport()) : + std::unique_ptr(new SocketTransport())) { + }*/ + TransportFactory(bool isDevice) { + if (isDevice) + mTransport = std::unique_ptr(new OmapiTransport()); + else + mTransport = std::unique_ptr(new SocketTransport()); + } + + ~TransportFactory() {} + + inline bool openConnection(connectionCallback cb) { + return mTransport->openConnection(cb); + } + + inline bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) { + return mTransport->sendData(inData, inLen, cb); + } + + inline bool sendData(const char* inData, const uint32_t inLen, std::vector& output) { + return mTransport->sendData(inData, inLen, output); + } + + inline bool closeConnection() { + return mTransport->closeConnection(); + } + + inline bool isConnected() { + return mTransport->isConnected(); + } + + private: + std::unique_ptr mTransport; + +}; +} +#endif /* __SE_TRANSPORT_FACTORY__ */ From 0b4e6964c1e29aa333fd6d03dcfe1110f0d67845 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 5 May 2020 14:26:18 +0530 Subject: [PATCH 23/58] construct and decode Apdu functions added --- .../4.1/JavacardKeymaster4Device.cpp | 78 ++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 2ae12410..74f540dd 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -35,12 +36,87 @@ namespace hardware { namespace keymaster { namespace V4_1 { +#define APDU_CLS 0x80 +#define APDU_P1 0x40 +#define APDU_P2 0x00 +#define APDU_RESP_STATUS_OK 0x9000 + +enum class Instruction { + INS_GENERATE_KEY_CMD = 0x10; + INS_IMPORT_KEY_CMD = 0x11; + INS_IMPORT_WRAPPED_KEY_CMD = 0x12; + INS_EXPORT_KEY_CMD = 0x13; + INS_ATTEST_KEY_CMD = 0x14; + INS_UPGRADE_KEY_CMD = 0x15; + INS_DELETE_KEY_CMD = 0x16; + INS_DELETE_ALL_KEYS_CMD = 0x17; + INS_ADD_RNG_ENTROPY_CMD = 0x18; + INS_COMPUTE_SHARED_HMAC_CMD = 0x19; + INS_DESTROY_ATT_IDS_CMD = 0x1A; + INS_VERIFY_AUTHORIZATION_CMD = 0x1B; + INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C; + INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D; + INS_GET_HW_INFO_CMD = 0x1E; + INS_BEGIN_OPERATION_CMD = 0x1F; + INS_UPDATE_OPERATION_CMD = 0x20; + INS_FINISH_OPERATION_CMD = 0x21; + INS_ABORT_OPERATION_CMD = 0x22; + INS_PROVISION_CMD = 0x23; +}; + +bool constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { + apduOut.push_back(static_cast(APDU_CLS)); //CLS + apduOut.push_back(static_cast(ins)); //INS + apduOut.push_back(static_cast(APDU_P1)); //P1 + apduOut.push_back(static_cast(APDU_P2)); //P2 + + if(UCHAR_MAX < inputData.size() && USHRT_MAX >= inputData.size()) { + //Extended length 3 bytes, starts with 0x00 + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(inputData.size() >> 8)); + apduOut.push_back(static_cast(inputData.size() & 0xFF)); + //Data + apduOut.insert(apduOut.end(), inputData.begin(), inputData.end()); + //Expected length of output + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(0x00)); //TODO Max expected out ?? + } else if(0 <= inputData.size() && UCHAR_MAX >= inputData.szie()) { + //Short length + apduOut.push_back(static_cast(inputData.size())); + //Data + if(inputData.size() > 0) + apduOut.insert(apduOut.end(), inputData.begin(), inputData.end()); + //Expected length of output + apduOut.push_back(static_cast(0x00));//TODO Max expected out ?? + } else { + return false; + } + + return true; +} + +bool parseApduMessage(std::vector& inputData, std::vector &resOut) { + uint16_t status = (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); + if (status == (uint16_t)APDU_RESP_STATUS_OK) { + resout.insert(resOut.begin(), inputData.begin(), inputData.end()-2); + return true; + } + return false; +} + JavacardKeymaster4Device::~JavacardKeymaster4Device() { } // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { - _hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); + //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); + std::vector output; + if(!constructApduMessage(INS_GET_HW_INFO_CMD, std::vector(), output ) { + LOG(ERROR) << "Failed to get hardware info"; + } + pTransport->openConnection(); + pTransport->sendData(output.data(), output.size() return Void(); } From d6fbd6ec319e4d370f13d5e8aca1b98930d1e24c Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 5 May 2020 11:56:29 +0100 Subject: [PATCH 24/58] Integration of Apdu message with getHardwareInfo function --- .../4.1/JavacardKeymaster4Device.cpp | 47 ++++++++++++---- HAL/keymaster/4.1/OmapiTransport.cpp | 4 ++ HAL/keymaster/4.1/SocketTransport.cpp | 56 ++++++++++++++----- .../include/JavacardKeymaster4Device.h | 7 +-- HAL/keymaster/include/Transport.h | 3 + HAL/keymaster/include/TransportFactory.h | 7 +-- 6 files changed, 90 insertions(+), 34 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 74f540dd..a1d6d50c 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" #define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" @@ -96,13 +97,14 @@ bool constructApduMessage(Instruction& ins, std::vector& inputData, std return true; } -bool parseApduMessage(std::vector& inputData, std::vector &resOut) { - uint16_t status = (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); - if (status == (uint16_t)APDU_RESP_STATUS_OK) { - resout.insert(resOut.begin(), inputData.begin(), inputData.end()-2); +uint16_t getStatus(std::vector& inputData) { + //Last two bytes are the status SW0SW1 + return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); + /*if (status == (uint16_t)APDU_RESP_STATUS_OK) { + resOut.insert(resOut.begin(), inputData.begin(), inputData.end()-2); return true; } - return false; + return false;*/ } JavacardKeymaster4Device::~JavacardKeymaster4Device() { @@ -111,12 +113,37 @@ JavacardKeymaster4Device::~JavacardKeymaster4Device() { // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); - std::vector output; - if(!constructApduMessage(INS_GET_HW_INFO_CMD, std::vector(), output ) { - LOG(ERROR) << "Failed to get hardware info"; + std::vector apdu; + std::vector resp; + std::unique_ptr item; + std::string message; + uint64_t securityLevel; + hidl_string jcKeymasterName; + hidl_string jcKeymasterAuthor; + + bool ret; + ret = constructApduMessage(INS_GET_HW_INFO_CMD, std::vector(), apdu ); + static_assert(ret, "Failed to get hardware info"); + + ret = pTransport->openConnection(); + static_assert(ret, "Failed to open connection with secure element"); + + ret = pTransport->sendData(apdu.data(), apdu.size(), resp); + static_assert(ret, "Failed to send data to secure element"); + + static_assert(APDU_RESP_STATUS_OK == getStatus(resp), "Failed to get response from secure element."); + + std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector temp; + cborConverter_.getUint64(item, 0, securityLevel); //SecurityLevel + cborConverter_.getBinaryArray(item, 1, temp); + jcKeymasterName.setToExternal(temp.data(), temp.size()); + temp.clear(); + cborConverter_.getBinaryArray(item, 2, temp); + jcKeymasterAuthor.setToExternal(temp.data(), temp.size()); } - pTransport->openConnection(); - pTransport->sendData(output.data(), output.size() + _hidl_cb(static_cast(securityLevel), jcKeymasterName, jcKeymasterAuthor); return Void(); } diff --git a/HAL/keymaster/4.1/OmapiTransport.cpp b/HAL/keymaster/4.1/OmapiTransport.cpp index 30ec5060..3a278bbd 100644 --- a/HAL/keymaster/4.1/OmapiTransport.cpp +++ b/HAL/keymaster/4.1/OmapiTransport.cpp @@ -28,6 +28,10 @@ namespace se_transport { +bool OmapiTransport::openConnection() { + return true; +} + bool OmapiTransport::openConnection(connectionCallback cb) { cb(true); return true; diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp index 6c23f5bc..c17bbdec 100644 --- a/HAL/keymaster/4.1/SocketTransport.cpp +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -27,27 +27,54 @@ namespace se_transport { +bool SocketTransport::openConnection() { + struct sockaddr_in serv_addr; + + if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + LOG(ERROR) << "Socket creation failed"; + return false; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + + // Convert IPv4 and IPv6 addresses from text to binary form + if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) + { + LOG(ERROR) << "Invalid address/ Address not supported."; + return false; + } + + if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + LOG(ERROR) << "Connection failed."; + return false; + } + return true; +} + bool SocketTransport::openConnection(connectionCallback cb) { - struct sockaddr_in serv_addr; + struct sockaddr_in serv_addr; - if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { + if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { LOG(ERROR) << "Socket creation failed"; - return false; - } - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) - { + return false; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + + // Convert IPv4 and IPv6 addresses from text to binary form + if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) + { LOG(ERROR) << "Invalid address/ Address not supported."; return false; } - if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) - { + if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { LOG(ERROR) << "Connection failed."; return false; } @@ -84,7 +111,6 @@ bool SocketTransport::sendData(const char* inData, const uint32_t inLen, std::ve output.push_back(buffer[i]); } return true; - } bool SocketTransport::closeConnection() { diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 0494890c..0795ea5f 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -41,10 +41,9 @@ using ::android::sp; class JavacardKeymaster4Device : public IKeymasterDevice { public: JavacardKeymaster4Device() { - if(android::base::GetBoolProperty("ro.kernel.qemu", false)) - pTransportFactory = std::make_unique(true); - else - pTransportFactory = std::make_unique(false); + /* TODO instead do we need to create object like this std::unique_ptr(new TransportFactory(true));*/ + pTransportFactory = std::make_unique( + android::base::GetBoolProperty("ro.kernel.qemu", false)); } virtual ~JavacardKeymaster4Device(); diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h index b07f2d20..3d38fc9a 100644 --- a/HAL/keymaster/include/Transport.h +++ b/HAL/keymaster/include/Transport.h @@ -26,6 +26,7 @@ class ITransport { public: virtual ~ITransport(){} virtual bool openConnection(connectionCallback cb) = 0; + virtual bool openConnection() = 0; virtual bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) = 0; virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) = 0; virtual bool closeConnection() = 0; @@ -38,6 +39,7 @@ class OmapiTransport : public ITransport { public: bool openConnection(connectionCallback cb) override; + bool openConnection() override; bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; bool closeConnection() override; @@ -49,6 +51,7 @@ class SocketTransport : public ITransport { public: bool openConnection(connectionCallback cb) override; + bool openConnection() override; bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; bool closeConnection() override; diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h index 3c631886..6fa8344d 100644 --- a/HAL/keymaster/include/TransportFactory.h +++ b/HAL/keymaster/include/TransportFactory.h @@ -23,11 +23,8 @@ namespace se_transport { class TransportFactory { public: - /*TransportFactory(bool isDevice) : mTransport( isDevice ? std::unique_ptr(new OmapiTransport()) : - std::unique_ptr(new SocketTransport())) { - }*/ - TransportFactory(bool isDevice) { - if (isDevice) + TransportFactory(bool isEmulator) { + if (!isEmulator) mTransport = std::unique_ptr(new OmapiTransport()); else mTransport = std::unique_ptr(new SocketTransport()); From 1dde4674313129b4dc7436ab550bfafbac0f9ce0 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 5 May 2020 20:28:18 +0530 Subject: [PATCH 25/58] Fixed compilation errors for getHardwareinfo --- .../4.1/JavacardKeymaster4Device.cpp | 108 ++++++++++-------- HAL/keymaster/4.1/OmapiTransport.cpp | 4 +- HAL/keymaster/4.1/SocketTransport.cpp | 4 +- HAL/keymaster/include/Transport.h | 12 +- HAL/keymaster/include/TransportFactory.h | 8 +- 5 files changed, 74 insertions(+), 62 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index a1d6d50c..86f85b96 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -43,29 +43,29 @@ namespace V4_1 { #define APDU_RESP_STATUS_OK 0x9000 enum class Instruction { - INS_GENERATE_KEY_CMD = 0x10; - INS_IMPORT_KEY_CMD = 0x11; - INS_IMPORT_WRAPPED_KEY_CMD = 0x12; - INS_EXPORT_KEY_CMD = 0x13; - INS_ATTEST_KEY_CMD = 0x14; - INS_UPGRADE_KEY_CMD = 0x15; - INS_DELETE_KEY_CMD = 0x16; - INS_DELETE_ALL_KEYS_CMD = 0x17; - INS_ADD_RNG_ENTROPY_CMD = 0x18; - INS_COMPUTE_SHARED_HMAC_CMD = 0x19; - INS_DESTROY_ATT_IDS_CMD = 0x1A; - INS_VERIFY_AUTHORIZATION_CMD = 0x1B; - INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C; - INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D; - INS_GET_HW_INFO_CMD = 0x1E; - INS_BEGIN_OPERATION_CMD = 0x1F; - INS_UPDATE_OPERATION_CMD = 0x20; - INS_FINISH_OPERATION_CMD = 0x21; - INS_ABORT_OPERATION_CMD = 0x22; - INS_PROVISION_CMD = 0x23; + INS_GENERATE_KEY_CMD = 0x10, + INS_IMPORT_KEY_CMD = 0x11, + INS_IMPORT_WRAPPED_KEY_CMD = 0x12, + INS_EXPORT_KEY_CMD = 0x13, + INS_ATTEST_KEY_CMD = 0x14, + INS_UPGRADE_KEY_CMD = 0x15, + INS_DELETE_KEY_CMD = 0x16, + INS_DELETE_ALL_KEYS_CMD = 0x17, + INS_ADD_RNG_ENTROPY_CMD = 0x18, + INS_COMPUTE_SHARED_HMAC_CMD = 0x19, + INS_DESTROY_ATT_IDS_CMD = 0x1A, + INS_VERIFY_AUTHORIZATION_CMD = 0x1B, + INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C, + INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D, + INS_GET_HW_INFO_CMD = 0x1E, + INS_BEGIN_OPERATION_CMD = 0x1F, + INS_UPDATE_OPERATION_CMD = 0x20, + INS_FINISH_OPERATION_CMD = 0x21, + INS_ABORT_OPERATION_CMD = 0x22, + INS_PROVISION_CMD = 0x23 }; -bool constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { +int32_t constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { apduOut.push_back(static_cast(APDU_CLS)); //CLS apduOut.push_back(static_cast(ins)); //INS apduOut.push_back(static_cast(APDU_P1)); //P1 @@ -82,7 +82,7 @@ bool constructApduMessage(Instruction& ins, std::vector& inputData, std apduOut.push_back(static_cast(0x00)); apduOut.push_back(static_cast(0x00)); apduOut.push_back(static_cast(0x00)); //TODO Max expected out ?? - } else if(0 <= inputData.size() && UCHAR_MAX >= inputData.szie()) { + } else if(0 <= inputData.size() && UCHAR_MAX >= inputData.size()) { //Short length apduOut.push_back(static_cast(inputData.size())); //Data @@ -91,20 +91,35 @@ bool constructApduMessage(Instruction& ins, std::vector& inputData, std //Expected length of output apduOut.push_back(static_cast(0x00));//TODO Max expected out ?? } else { - return false; + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::INSUFFICIENT_BUFFER_SPACE); } - return true; + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK);//success } uint16_t getStatus(std::vector& inputData) { //Last two bytes are the status SW0SW1 return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); - /*if (status == (uint16_t)APDU_RESP_STATUS_OK) { - resOut.insert(resOut.begin(), inputData.begin(), inputData.end()-2); - return true; +} + +inline int32_t sendData(std::unique_ptr& transport, Instruction ins, std::vector& inData, +std::vector& response) { + std::vector apdu; + int32_t ret = constructApduMessage(ins, inData, apdu); + if(ret != 0) return ret; + + if(!transport->openConnection()) { + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + } + + if(!transport->sendData(apdu.data(), apdu.size(), response)) { + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + } + + if(APDU_RESP_STATUS_OK != getStatus(response)) { + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR); } - return false;*/ + return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK);//success } JavacardKeymaster4Device::~JavacardKeymaster4Device() { @@ -113,35 +128,28 @@ JavacardKeymaster4Device::~JavacardKeymaster4Device() { // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); - std::vector apdu; std::vector resp; + std::vector input; + const uint8_t* pos; std::unique_ptr item; std::string message; - uint64_t securityLevel; + uint64_t securityLevel = static_cast(SecurityLevel::STRONGBOX); hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - bool ret; - ret = constructApduMessage(INS_GET_HW_INFO_CMD, std::vector(), apdu ); - static_assert(ret, "Failed to get hardware info"); - - ret = pTransport->openConnection(); - static_assert(ret, "Failed to open connection with secure element"); - - ret = pTransport->sendData(apdu.data(), apdu.size(), resp); - static_assert(ret, "Failed to send data to secure element"); + int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); - static_assert(APDU_RESP_STATUS_OK == getStatus(resp), "Failed to get response from secure element."); - - std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - std::vector temp; - cborConverter_.getUint64(item, 0, securityLevel); //SecurityLevel - cborConverter_.getBinaryArray(item, 1, temp); - jcKeymasterName.setToExternal(temp.data(), temp.size()); - temp.clear(); - cborConverter_.getBinaryArray(item, 2, temp); - jcKeymasterAuthor.setToExternal(temp.data(), temp.size()); + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector temp; + cborConverter_.getUint64(item, 0, securityLevel); //SecurityLevel + cborConverter_.getBinaryArray(item, 1, temp); + jcKeymasterName = std::string(temp.begin(), temp.end()); + temp.clear(); + cborConverter_.getBinaryArray(item, 2, temp); + jcKeymasterAuthor = std::string(temp.begin(), temp.end()); + } } _hidl_cb(static_cast(securityLevel), jcKeymasterName, jcKeymasterAuthor); return Void(); diff --git a/HAL/keymaster/4.1/OmapiTransport.cpp b/HAL/keymaster/4.1/OmapiTransport.cpp index 3a278bbd..a981edb2 100644 --- a/HAL/keymaster/4.1/OmapiTransport.cpp +++ b/HAL/keymaster/4.1/OmapiTransport.cpp @@ -37,14 +37,14 @@ bool OmapiTransport::openConnection(connectionCallback cb) { return true; } -bool OmapiTransport::sendData(const char* inData, const uint32_t inLen, responseCallback cb) { +bool OmapiTransport::sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) { std::vector test(inData, inData+inLen); cb(test); return true; } -bool OmapiTransport::sendData(const char* inData, const uint32_t inLen, std::vector& output) { +bool OmapiTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { std::vector test(inData, inData+inLen); output = std::move(test); return true; diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp index c17bbdec..11ecd6d8 100644 --- a/HAL/keymaster/4.1/SocketTransport.cpp +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -82,7 +82,7 @@ bool SocketTransport::openConnection(connectionCallback cb) { return true; } -bool SocketTransport::sendData(const char* data, uint32_t dataSize, responseCallback cb) { +bool SocketTransport::sendData(const uint8_t* data, const size_t dataSize, responseCallback cb) { uint8_t buffer[MAX_RECV_BUFFER_SIZE]; if (0 > send(mSocket, data ,dataSize , 0 )) { LOG(ERROR) << "Failed to send data over socket."; @@ -97,7 +97,7 @@ bool SocketTransport::sendData(const char* data, uint32_t dataSize, responseCall return true; } -bool SocketTransport::sendData(const char* inData, const uint32_t inLen, std::vector& output) { +bool SocketTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { uint8_t buffer[MAX_RECV_BUFFER_SIZE]; if (0 > send(mSocket, inData, inLen , 0 )) { LOG(ERROR) << "Failed to send data over socket."; diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h index 3d38fc9a..a6b917b3 100644 --- a/HAL/keymaster/include/Transport.h +++ b/HAL/keymaster/include/Transport.h @@ -27,8 +27,8 @@ class ITransport { virtual ~ITransport(){} virtual bool openConnection(connectionCallback cb) = 0; virtual bool openConnection() = 0; - virtual bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) = 0; - virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) = 0; + virtual bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) = 0; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) = 0; virtual bool closeConnection() = 0; virtual bool isConnected() = 0; @@ -40,8 +40,8 @@ class OmapiTransport : public ITransport { bool openConnection(connectionCallback cb) override; bool openConnection() override; - bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; - virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; + bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) override; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; bool closeConnection() override; bool isConnected() override; @@ -52,8 +52,8 @@ class SocketTransport : public ITransport { public: bool openConnection(connectionCallback cb) override; bool openConnection() override; - bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) override; - virtual bool sendData(const char* inData, const uint32_t inLen, std::vector& output) override; + bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) override; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; bool closeConnection() override; bool isConnected() override; private: diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h index 6fa8344d..f8d9240b 100644 --- a/HAL/keymaster/include/TransportFactory.h +++ b/HAL/keymaster/include/TransportFactory.h @@ -36,11 +36,15 @@ class TransportFactory { return mTransport->openConnection(cb); } - inline bool sendData(const char* inData, const uint32_t inLen, responseCallback cb) { + inline bool openConnection() { + return mTransport->openConnection(); + } + + inline bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) { return mTransport->sendData(inData, inLen, cb); } - inline bool sendData(const char* inData, const uint32_t inLen, std::vector& output) { + inline bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { return mTransport->sendData(inData, inLen, output); } From 8a43205d9dcce06ecddbd426aa1141d64df9d681 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Fri, 8 May 2020 21:09:13 +0530 Subject: [PATCH 26/58] Modified getItemAtPos method --- HAL/keymaster/4.1/CborConverter.cpp | 18 +++++++++++++----- HAL/keymaster/include/CborConverter.h | 15 ++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 2679697a..c0ec86ef 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -72,8 +72,9 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) { bool ret = false; + std::unique_ptr arrayItem(nullptr); - const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + getItemAtPos(item, pos, arrayItem); if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) return ret; @@ -140,7 +141,9 @@ ParseResult CborConverter::decodeData(const std::vector cborData) { bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { bool ret = false; - const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + std::unique_ptr arrayItem(nullptr); + + getItemAtPos(item, pos, arrayItem); if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) return ret; const Array* arr = arrayItem.get()->asArray(); @@ -157,7 +160,9 @@ bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { bool ret = false; - const std::unique_ptr& strItem = getItemAtPos(item, pos); + std::unique_ptr strItem(nullptr); + + getItemAtPos(item, pos, strItem); if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) return ret; @@ -173,10 +178,12 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { std::vector paramValue; bool ret = false; + std::unique_ptr arrayItem(nullptr); //1. Get ArrayItem //2. First item in the array seed; second item in the array is nonce. - const std::unique_ptr& arrayItem = getItemAtPos(item, pos); + + getItemAtPos(item, pos, arrayItem); if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) return ret; @@ -276,7 +283,8 @@ bool CborConverter::getVerificationToken(const std::unique_ptr& item, cons bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { bool ret = false; - const std::unique_ptr& mapItem = getItemAtPos(item, pos); + std::unique_ptr mapItem(nullptr); + getItemAtPos(item, pos, mapItem); if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) return ret; diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 84e86299..5cd60584 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -95,24 +95,25 @@ class CborConverter inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } bool getKeyparameter(const std::pair&, const std::unique_ptr&> pair, KeyParameter& keyParam); - inline const std::unique_ptr& getItemAtPos(const std::unique_ptr& item, const uint32_t pos) { - const Array* arr = nullptr; + inline void getItemAtPos(const std::unique_ptr& item, const uint32_t pos, std::unique_ptr& subItem) { + Array* arr = nullptr; if (MajorType::ARRAY != getType(item)) { - return EMPTY(std::unique_ptr); + return; } - arr = item.get()->asArray(); + arr = const_cast(item.get()->asArray()); if (arr->size() < (pos + 1)) { - return EMPTY(std::unique_ptr); + return; } - return (*arr)[pos]; + subItem = std::move((*arr)[pos]); } }; template bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { bool ret = false; - const std::unique_ptr& intItem = getItemAtPos(item, pos); + std::unique_ptr intItem(nullptr); + getItemAtPos(item, pos, intItem); if ((intItem == nullptr) || (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || From f9183607f50a8a0d16e140b43ee9219b2ea6ec31 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Fri, 8 May 2020 22:15:37 +0530 Subject: [PATCH 27/58] Calling transport send method in all the APIs --- .../4.1/JavacardKeymaster4Device.cpp | 348 ++++++++++-------- 1 file changed, 203 insertions(+), 145 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 86f85b96..26d478f3 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -62,7 +62,9 @@ enum class Instruction { INS_UPDATE_OPERATION_CMD = 0x20, INS_FINISH_OPERATION_CMD = 0x21, INS_ABORT_OPERATION_CMD = 0x22, - INS_PROVISION_CMD = 0x23 + INS_PROVISION_CMD = 0x23, + INS_DEVICE_LOCKED_CMD = 0x24, + INS_EARLY_BOOT_ENDED_CMD = 0x25 }; int32_t constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { @@ -158,17 +160,20 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { std::vector cborData; const uint8_t* pos; + std::vector input; std::unique_ptr item; std::string message; ::android::hardware::keymaster::V4_0::HmacSharingParameters hmacSharingParameters; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - // TODO Call OMAPI layer and get the Cbor format data. + int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); - std::tie(item, pos, message) = parse(cborData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Error Code - cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters); //HmacSharingParameters. + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborData.begin(), cborData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters); //HmacSharingParameters. + } } _hidl_cb(errorCode, hmacSharingParameters); return Void(); @@ -178,6 +183,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi cppbor::Array array; const uint8_t* pos; std::unique_ptr item; + std::vector cborOutData; std::string message; hidl_vec sharingCheck; @@ -195,15 +201,16 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi array.add(std::move(innerArray)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Error Code - cborConverter_.getBinaryArray(item, 1, bstr); - sharingCheck.setToExternal(bstr.data(), bstr.size()); + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getBinaryArray(item, 1, bstr); + sharingCheck.setToExternal(bstr.data(), bstr.size()); + } } _hidl_cb(errorCode, sharingCheck); return Void(); @@ -213,6 +220,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cppbor::Array array; const uint8_t* pos; std::unique_ptr item; + std::vector cborOutData; std::string message; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::keymaster::V4_0::VerificationToken verificationToken; @@ -223,13 +231,14 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getVerificationToken(item, 1, verificationToken); + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getVerificationToken(item, 1, verificationToken); + } } _hidl_cb(errorCode, verificationToken); return Void(); @@ -238,6 +247,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { const uint8_t* pos; cppbor::Array array; + std::vector cborOutData; std::unique_ptr item; std::string message; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; @@ -246,12 +256,13 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device array.add(std::vector(data)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -262,22 +273,25 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::har std::unique_ptr item; std::string message; hidl_vec keyBlob; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - /* TODO keyBlob is BSTR */ - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); - cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } } _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); @@ -289,6 +303,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardw std::unique_ptr item; std::string message; hidl_vec keyBlob; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; @@ -296,16 +311,19 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardw array.add(static_cast(keyFormat)); array.add(std::vector(keyData)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - /* TODO keyBlob is BSTR */ - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); - cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } } _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); @@ -317,6 +335,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& std::unique_ptr item; std::string message; hidl_vec keyBlob; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; @@ -327,16 +346,19 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(passwordSid); array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - /* TODO keyBlob is BSTR */ - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); - cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO keyBlob is BSTR */ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } } _hidl_cb(errorCode, keyBlob, keyCharacteristics); @@ -348,6 +370,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; @@ -355,12 +378,15 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(clientId)); array.add(std::vector(appData)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics); + } } _hidl_cb(errorCode, keyCharacteristics); return Void(); @@ -372,6 +398,7 @@ Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster: std::unique_ptr item; std::string message; hidl_vec keyMaterial; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; array.add(static_cast(keyFormat)); @@ -379,15 +406,18 @@ Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster: array.add(std::vector(clientId)); array.add(std::vector(appData)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - /* TODO Keyblobc - BSTR()*/ - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getBinaryArray(item, 1, bstr); - keyMaterial.setToExternal(bstr.data(), bstr.size()); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO Keyblobc - BSTR()*/ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyMaterial.setToExternal(bstr.data(), bstr.size()); + } } _hidl_cb(errorCode, keyMaterial); return Void(); @@ -399,18 +429,22 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA std::unique_ptr item; std::string message; hidl_vec keyBlob; + std::vector cborOutData; ::android::hardware::hidl_vec<::android::hardware::hidl_vec> certChain; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyToAttest)); cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getMultiBinaryArray(item, 1, certChain); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getMultiBinaryArray(item, 1, certChain); + } } _hidl_cb(errorCode, certChain); return Void(); @@ -422,20 +456,24 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl std::unique_ptr item; std::string message; hidl_vec upgradedKeyBlob; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyBlobToUpgrade)); cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - /* TODO Keyblob BSTR(ARRAY) */ - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getBinaryArray(item, 1, bstr); - upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); + + int32_t ret = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO Keyblob BSTR(ARRAY) */ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); + } } _hidl_cb(errorCode, upgradedKeyBlob); return Void(); @@ -446,17 +484,19 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -465,15 +505,17 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; + std::vector input; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + int32_t ret = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -482,15 +524,17 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; + std::vector input; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + int32_t ret = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -506,6 +550,7 @@ Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_ } else { cppbor::Array array; const uint8_t* pos; + std::vector cborOutData; std::unique_ptr item; std::string message; @@ -516,14 +561,15 @@ Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_ cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getUint64(item, 2, operationHandle); + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getUint64(item, 2, operationHandle); + } } } _hidl_cb(errorCode, outParams, operationHandle); @@ -535,6 +581,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; uint32_t inputConsumed = 0; @@ -548,17 +595,18 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. - - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getUint64(item, 1, inputConsumed); - cborConverter_.getKeyParameters(item, 2, outParams); - cborConverter_.getBinaryArray(item, 3, bstr); - output.setToExternal(bstr.data(), bstr.size()); + int32_t ret = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getUint64(item, 1, inputConsumed); + cborConverter_.getKeyParameters(item, 2, outParams); + cborConverter_.getBinaryArray(item, 3, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } } _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); @@ -569,6 +617,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; hidl_vec output; @@ -582,16 +631,17 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getBinaryArray(item, 2, bstr); - output.setToExternal(bstr.data(), bstr.size()); + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getBinaryArray(item, 2, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } } _hidl_cb(errorCode, outParams, output); return Void(); @@ -602,18 +652,20 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; /* Convert input data to cbor format */ array.add(operationHandle); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode<::android::hardware::keymaster::V4_0::ErrorCode>(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode<::android::hardware::keymaster::V4_0::ErrorCode>(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -624,6 +676,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; /* Convert input data to cbor format */ @@ -631,12 +684,14 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + /* TODO DeviceLocked command handled inside HAL */ + int32_t ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } @@ -645,14 +700,17 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device const uint8_t* pos; std::unique_ptr item; std::string message; + std::vector cborOutData; + std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - // TODO Call OMAPI layer and sent the cbor data and get the Cbor format data back. + int32_t ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); - std::vector cborOutData; /*Received from OMAPI */ - std::tie(item, pos, message) = parse(cborOutData); - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } } return errorCode; } From 5f96e483402415e82fcf93f8db7ef39d71755777 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 13 May 2020 19:12:41 +0530 Subject: [PATCH 28/58] some code refactoring --- .../4.1/JavacardKeymaster4Device.cpp | 234 +++++++++--------- HAL/keymaster/Android.bp | 38 +-- .../include/JavacardKeymaster4Device.h | 71 +++--- 3 files changed, 156 insertions(+), 187 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 26d478f3..2f3c3684 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -15,33 +15,26 @@ ** limitations under the License. */ -#define LOG_TAG "android.hardware.keymaster@4.1-service.javacard" -#include -#include #include #include -#include -#include -#include -#include #include #include #include #include +#include -#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" -#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" - -namespace android { -namespace hardware { -namespace keymaster { -namespace V4_1 { - +//#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" +//#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" #define APDU_CLS 0x80 #define APDU_P1 0x40 #define APDU_P2 0x00 #define APDU_RESP_STATUS_OK 0x9000 +namespace keymaster { +namespace V4_1 { +namespace javacard { + + enum class Instruction { INS_GENERATE_KEY_CMD = 0x10, INS_IMPORT_KEY_CMD = 0x11, @@ -67,7 +60,7 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x25 }; -int32_t constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { +ErrorCode constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { apduOut.push_back(static_cast(APDU_CLS)); //CLS apduOut.push_back(static_cast(ins)); //INS apduOut.push_back(static_cast(APDU_P1)); //P1 @@ -83,7 +76,7 @@ int32_t constructApduMessage(Instruction& ins, std::vector& inputData, //Expected length of output apduOut.push_back(static_cast(0x00)); apduOut.push_back(static_cast(0x00)); - apduOut.push_back(static_cast(0x00)); //TODO Max expected out ?? + apduOut.push_back(static_cast(0x00));//Accepting complete length of output at a time } else if(0 <= inputData.size() && UCHAR_MAX >= inputData.size()) { //Short length apduOut.push_back(static_cast(inputData.size())); @@ -91,12 +84,13 @@ int32_t constructApduMessage(Instruction& ins, std::vector& inputData, if(inputData.size() > 0) apduOut.insert(apduOut.end(), inputData.begin(), inputData.end()); //Expected length of output - apduOut.push_back(static_cast(0x00));//TODO Max expected out ?? + apduOut.push_back(static_cast(0x00));//Accepting complete length of output at a time + } else { - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::INSUFFICIENT_BUFFER_SPACE); + return (ErrorCode::INSUFFICIENT_BUFFER_SPACE); } - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK);//success + return (ErrorCode::OK);//success } uint16_t getStatus(std::vector& inputData) { @@ -104,27 +98,24 @@ uint16_t getStatus(std::vector& inputData) { return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); } -inline int32_t sendData(std::unique_ptr& transport, Instruction ins, std::vector& inData, +inline ErrorCode sendData(std::unique_ptr& transport, Instruction ins, std::vector& inData, std::vector& response) { std::vector apdu; - int32_t ret = constructApduMessage(ins, inData, apdu); - if(ret != 0) return ret; + ErrorCode ret = constructApduMessage(ins, inData, apdu); + if(ret != ErrorCode::OK) return ret; if(!transport->openConnection()) { - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if(!transport->sendData(apdu.data(), apdu.size(), response)) { - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if(APDU_RESP_STATUS_OK != getStatus(response)) { - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR); + return (ErrorCode::UNKNOWN_ERROR); } - return static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK);//success -} - -JavacardKeymaster4Device::~JavacardKeymaster4Device() { + return (ErrorCode::OK);//success } // Methods from IKeymasterDevice follow. @@ -139,9 +130,9 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(ret == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector temp; @@ -163,12 +154,12 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa std::vector input; std::unique_ptr item; std::string message; - ::android::hardware::keymaster::V4_0::HmacSharingParameters hmacSharingParameters; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + HmacSharingParameters hmacSharingParameters; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + errorCode = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborData.begin(), cborData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Error Code @@ -179,7 +170,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa return Void(); } -Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { +Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec& params, computeSharedHmac_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; @@ -187,7 +178,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi std::string message; hidl_vec sharingCheck; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; std::vector tempVec; cppbor::Array innerArray; for(size_t i = 0; i < params.size(); ++i) { @@ -201,9 +192,9 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi array.add(std::move(innerArray)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -216,14 +207,14 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::androi return Void(); } -Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { +Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec& parametersToVerify, const HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::vector cborOutData; std::string message; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::keymaster::V4_0::VerificationToken verificationToken; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + VerificationToken verificationToken; /* Convert input data to cbor format */ array.add(operationHandle); @@ -231,9 +222,9 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -244,21 +235,21 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { +Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { const uint8_t* pos; cppbor::Array array; std::vector cborOutData; std::unique_ptr item; std::string message; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; /* Convert input data to cbor format */ array.add(std::vector(data)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -267,22 +258,22 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device return errorCode; } -Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::generateKey(const hidl_vec& keyParams, generateKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec keyBlob; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -297,24 +288,24 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::har return Void(); } -Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec keyBlob; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; cborConverter_.addKeyparameters(array, keyParams); array.add(static_cast(keyFormat)); array.add(std::vector(keyData)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -329,15 +320,15 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardw return Void(); } -Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec keyBlob; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; array.add(std::vector(wrappedKeyData)); array.add(std::vector(wrappingKeyBlob)); @@ -347,9 +338,9 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO keyBlob is BSTR */ @@ -371,17 +362,17 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec item; std::string message; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::keymaster::V4_0::KeyCharacteristics keyCharacteristics; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; array.add(std::vector(keyBlob)); array.add(std::vector(clientId)); array.add(std::vector(appData)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -392,14 +383,14 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec JavacardKeymaster4Device::exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec keyMaterial; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; array.add(static_cast(keyFormat)); array.add(std::vector(keyBlob)); @@ -407,9 +398,9 @@ Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster: array.add(std::vector(appData)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO Keyblobc - BSTR()*/ @@ -423,23 +414,23 @@ Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster: return Void(); } -Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec keyBlob; std::vector cborOutData; - ::android::hardware::hidl_vec<::android::hardware::hidl_vec> certChain; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + hidl_vec> certChain; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyToAttest)); cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -450,22 +441,22 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA return Void(); } -Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec& upgradeParams, upgradeKey_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; hidl_vec upgradedKeyBlob; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyBlobToUpgrade)); cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO Keyblob BSTR(ARRAY) */ @@ -479,20 +470,20 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { +Return JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -501,17 +492,17 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device return errorCode; } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteAllKeys() { +Return JavacardKeymaster4Device::deleteAllKeys() { const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; std::vector input; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - int32_t ret = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -520,17 +511,17 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device return errorCode; } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::destroyAttestationIds() { +Return JavacardKeymaster4Device::destroyAttestationIds() { const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; std::vector input; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - int32_t ret = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -539,13 +530,13 @@ Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device return errorCode; } -Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) { - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; +Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec& inParams, const HardwareAuthToken& authToken, begin_cb _hidl_cb) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; uint64_t operationHandle = 0; - if (::android::hardware::keymaster::V4_0::KeyPurpose::ENCRYPT == purpose || - ::android::hardware::keymaster::V4_0::KeyPurpose::VERIFY == purpose) { + if (KeyPurpose::ENCRYPT == purpose || + KeyPurpose::VERIFY == purpose) { /* Public key operations are handled here*/ } else { cppbor::Array array; @@ -561,9 +552,9 @@ Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_ cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -576,14 +567,14 @@ Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_ return Void(); } -Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) { +Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; uint32_t inputConsumed = 0; hidl_vec output; @@ -595,9 +586,9 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -612,14 +603,14 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi return Void(); } -Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) { +Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; - ::android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter> outParams; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; hidl_vec output; /* Convert input data to cbor format */ @@ -631,9 +622,9 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -647,31 +638,31 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::abort(uint64_t operationHandle) { +Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; - ::android::hardware::keymaster::V4_0::ErrorCode errorCode = ::android::hardware::keymaster::V4_0::ErrorCode::UNKNOWN_ERROR; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; /* Convert input data to cbor format */ array.add(operationHandle); std::vector cborData = array.encode(); - int32_t ret = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(errorCode == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { - cborConverter_.getErrorCode<::android::hardware::keymaster::V4_0::ErrorCode>(item, 0, errorCode); //Errorcode + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode } } return errorCode; } // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. -Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) { +Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) { cppbor::Array array; const uint8_t* pos; std::unique_ptr item; @@ -685,9 +676,9 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - int32_t ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(ret == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -704,9 +695,9 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - int32_t ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); - if(ret == static_cast(::android::hardware::keymaster::V4_0::ErrorCode::OK)) { + if(ret == ErrorCode::OK) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -715,7 +706,6 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device return errorCode; } +} // javacard } // namespace V4_1 } // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index d708814f..65302a74 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -13,37 +13,9 @@ // limitations under the License. // -cc_binary { - name: "android.hardware.keymaster@4.1-javacard-service", - init_rc: ["4.1/android.hardware.keymaster@4.1-service.javacard.rc"], - srcs: [ - "4.1/service.cpp", - "4.1/JavacardKeymaster4Device.cpp", - "4.1/CborConverter.cpp" - ], - local_include_dirs: [ - "include", - ], - shared_libs: [ - "liblog", - "libcutils", - "libdl", - "libbase", - "libutils", - "libhardware", - "libhidlbase", - "libkeymaster_messages", - "libcppbor_external", - "omapi_external", - "android.hardware.keymaster@4.1", - "jc_transport", - ], -} - cc_library { - name: "android.hardware.keymaster@4.1-javacard", + name: "libJavacardKeymaster41", srcs: [ - "4.1/service.cpp", "4.1/JavacardKeymaster4Device.cpp", "4.1/CborConverter.cpp", ], @@ -63,14 +35,12 @@ cc_library { "omapi_external", "android.hardware.keymaster@4.1", "android.hardware.keymaster@4.0", - "jc_transport", + "libjc_transport", ], } - - cc_library { - name: "jc_transport", + name: "libjc_transport", host_supported: true, vendor_available: true, @@ -85,7 +55,5 @@ cc_library { "libbinder", "libbase", "liblog", - "libutils", - "libcurl" ], } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 0795ea5f..11318f20 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -15,8 +15,8 @@ ** limitations under the License. */ -#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ -#define ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ +#ifndef KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ +#define KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ #include #include @@ -25,18 +25,30 @@ #include "CborConverter.h" #include "TransportFactory.h" -namespace android { -namespace hardware { namespace keymaster { namespace V4_1 { +namespace javacard { -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::sp; + +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; +using ::android::hardware::keymaster::V4_0::HardwareAuthToken; +using ::android::hardware::keymaster::V4_0::HmacSharingParameters; +using ::android::hardware::keymaster::V4_0::KeyCharacteristics; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::OperationHandle; +using ::android::hardware::keymaster::V4_0::SecurityLevel; +using ::android::hardware::keymaster::V4_0::VerificationToken; +using ::android::hardware::keymaster::V4_1::IKeymasterDevice; +using ::android::hardware::keymaster::V4_1::Tag; + +using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode; class JavacardKeymaster4Device : public IKeymasterDevice { public: @@ -46,41 +58,40 @@ class JavacardKeymaster4Device : public IKeymasterDevice { android::base::GetBoolProperty("ro.kernel.qemu", false)); } - virtual ~JavacardKeymaster4Device(); + virtual ~JavacardKeymaster4Device() {} // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; Return getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override; - Return computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) override; - Return verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> addRngEntropy(const hidl_vec& data) override; - Return generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) override; - Return importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) override; - Return importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) override; + Return computeSharedHmac(const hidl_vec& params, computeSharedHmac_cb _hidl_cb) override; + Return verifyAuthorization(uint64_t operationHandle, const hidl_vec& parametersToVerify, const HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) override; + Return addRngEntropy(const hidl_vec& data) override; + Return generateKey(const hidl_vec& keyParams, generateKey_cb _hidl_cb) override; + Return importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) override; + Return importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) override; Return getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) override; - Return exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, 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<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) override; - Return upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteKey(const hidl_vec& keyBlob) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteAllKeys() override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> destroyAttestationIds() override; - Return begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) override; - Return update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) override; - Return finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> abort(uint64_t operationHandle) override; + Return exportKey(KeyFormat keyFormat, 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 destroyAttestationIds() override; + Return begin(KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec& inParams, const HardwareAuthToken& authToken, begin_cb _hidl_cb) override; + Return update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) override; + Return finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) override; + Return abort(uint64_t operationHandle) override; // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. - Return<::android::hardware::keymaster::V4_1::ErrorCode> deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) override; - Return<::android::hardware::keymaster::V4_1::ErrorCode> earlyBootEnded() override; + Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; + Return earlyBootEnded() override; protected: CborConverter cborConverter_; std::unique_ptr pTransportFactory; }; +} // namespace javacard } // namespace V4_1 } // namespace keymaster -} // namespace hardware -} // namespace android -#endif // ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ +#endif // KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ From e50e516ee832f1e90203fcf807f246e2eeb27398 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 13 May 2020 22:00:02 +0530 Subject: [PATCH 29/58] openConnection moved to Constructor --- HAL/keymaster/4.1/JavacardKeymaster4Device.cpp | 6 +++--- HAL/keymaster/include/JavacardKeymaster4Device.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 2f3c3684..0c28f055 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -104,9 +104,9 @@ std::vector& response) { ErrorCode ret = constructApduMessage(ins, inData, apdu); if(ret != ErrorCode::OK) return ret; - if(!transport->openConnection()) { - return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); - } + //if(!transport->openConnection()) { + // return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + //} if(!transport->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 11318f20..0ced32ab 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -56,6 +56,7 @@ class JavacardKeymaster4Device : public IKeymasterDevice { /* TODO instead do we need to create object like this std::unique_ptr(new TransportFactory(true));*/ pTransportFactory = std::make_unique( android::base::GetBoolProperty("ro.kernel.qemu", false)); + pTransportFactory->openConnection(); } virtual ~JavacardKeymaster4Device() {} From 53b9d1c3837e855d9d80d84b66830c91360dddba Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 13 May 2020 23:00:15 +0530 Subject: [PATCH 30/58] Remove unnecessary functions and add assert statement --- HAL/keymaster/4.1/OmapiTransport.cpp | 12 ------ HAL/keymaster/4.1/SocketTransport.cpp | 43 ------------------- .../include/JavacardKeymaster4Device.h | 8 ++-- HAL/keymaster/include/Transport.h | 9 ---- HAL/keymaster/include/TransportFactory.h | 8 ---- 5 files changed, 4 insertions(+), 76 deletions(-) diff --git a/HAL/keymaster/4.1/OmapiTransport.cpp b/HAL/keymaster/4.1/OmapiTransport.cpp index a981edb2..5aaefc91 100644 --- a/HAL/keymaster/4.1/OmapiTransport.cpp +++ b/HAL/keymaster/4.1/OmapiTransport.cpp @@ -32,18 +32,6 @@ bool OmapiTransport::openConnection() { return true; } -bool OmapiTransport::openConnection(connectionCallback cb) { - cb(true); - return true; -} - -bool OmapiTransport::sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) { - std::vector test(inData, inData+inLen); - cb(test); - return true; - -} - bool OmapiTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { std::vector test(inData, inData+inLen); output = std::move(test); diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp index 11ecd6d8..b03262d1 100644 --- a/HAL/keymaster/4.1/SocketTransport.cpp +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -54,49 +54,6 @@ bool SocketTransport::openConnection() { return true; } -bool SocketTransport::openConnection(connectionCallback cb) { - struct sockaddr_in serv_addr; - - if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - LOG(ERROR) << "Socket creation failed"; - return false; - } - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) - { - LOG(ERROR) << "Invalid address/ Address not supported."; - return false; - } - - if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) - { - LOG(ERROR) << "Connection failed."; - return false; - } - cb(true);// This can be used for Asynchronous calls. - return true; -} - -bool SocketTransport::sendData(const uint8_t* data, const size_t dataSize, responseCallback cb) { - uint8_t buffer[MAX_RECV_BUFFER_SIZE]; - if (0 > send(mSocket, data ,dataSize , 0 )) { - LOG(ERROR) << "Failed to send data over socket."; - return false; - } - ssize_t valRead = read( mSocket , buffer, MAX_RECV_BUFFER_SIZE); - if(0 > valRead) { - LOG(ERROR) << "Failed to read data from socket."; - } - std::vector output(buffer, buffer+valRead); - cb(output); - return true; -} - bool SocketTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { uint8_t buffer[MAX_RECV_BUFFER_SIZE]; if (0 > send(mSocket, inData, inLen , 0 )) { diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 0ced32ab..6bb62387 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -18,6 +18,7 @@ #ifndef KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ #define KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ +#include #include #include #include @@ -53,10 +54,9 @@ using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode; class JavacardKeymaster4Device : public IKeymasterDevice { public: JavacardKeymaster4Device() { - /* TODO instead do we need to create object like this std::unique_ptr(new TransportFactory(true));*/ - pTransportFactory = std::make_unique( - android::base::GetBoolProperty("ro.kernel.qemu", false)); - pTransportFactory->openConnection(); + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); } virtual ~JavacardKeymaster4Device() {} diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h index a6b917b3..aadb3f00 100644 --- a/HAL/keymaster/include/Transport.h +++ b/HAL/keymaster/include/Transport.h @@ -19,15 +19,10 @@ namespace se_transport { -typedef void (*connectionCallback)(bool connected); -typedef void (*responseCallback)(std::vector output); - class ITransport { public: virtual ~ITransport(){} - virtual bool openConnection(connectionCallback cb) = 0; virtual bool openConnection() = 0; - virtual bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) = 0; virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) = 0; virtual bool closeConnection() = 0; virtual bool isConnected() = 0; @@ -38,9 +33,7 @@ class OmapiTransport : public ITransport { public: - bool openConnection(connectionCallback cb) override; bool openConnection() override; - bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) override; virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; bool closeConnection() override; bool isConnected() override; @@ -50,9 +43,7 @@ class OmapiTransport : public ITransport { class SocketTransport : public ITransport { public: - bool openConnection(connectionCallback cb) override; bool openConnection() override; - bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) override; virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; bool closeConnection() override; bool isConnected() override; diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h index f8d9240b..2e01e66b 100644 --- a/HAL/keymaster/include/TransportFactory.h +++ b/HAL/keymaster/include/TransportFactory.h @@ -32,18 +32,10 @@ class TransportFactory { ~TransportFactory() {} - inline bool openConnection(connectionCallback cb) { - return mTransport->openConnection(cb); - } - inline bool openConnection() { return mTransport->openConnection(); } - inline bool sendData(const uint8_t* inData, const size_t inLen, responseCallback cb) { - return mTransport->sendData(inData, inLen, cb); - } - inline bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { return mTransport->sendData(inData, inLen, output); } From f0c7317c40da10be731ffdb5b4867abaf6d3de04 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 14 May 2020 21:25:37 +0530 Subject: [PATCH 31/58] Added documentation for transport classes. Removed unnecessary includes. --- HAL/keymaster/4.1/CborConverter.cpp | 29 ++---- HAL/keymaster/4.1/SocketTransport.cpp | 1 - HAL/keymaster/include/CborConverter.h | 96 ++++++++++++++----- .../include/JavacardKeymaster4Device.h | 3 +- HAL/keymaster/include/Transport.h | 56 ++++++++++- HAL/keymaster/include/TransportFactory.h | 20 ++++ 6 files changed, 154 insertions(+), 51 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index c0ec86ef..de2b0b75 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -15,26 +15,9 @@ ** limitations under the License. */ -#include -#include -#include -#include -#include #include -using namespace cppbor; -using ::android::hardware::keymaster::V4_0::KeyParameter; -using ::android::hardware::keymaster::V4_0::TagType; -#define UNUSED(A) A = A - -bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { - UNUSED(value); - UNUSED(keyParam); - UNUSED(tag); - return false; -} - -bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { +bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams) { Map map; for(size_t i = 0; i < keyParams.size(); i++) { KeyParameter param = keyParams[i]; @@ -70,7 +53,7 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl } bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, - ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) { + KeyCharacteristics& keyCharacteristics) { bool ret = false; std::unique_ptr arrayItem(nullptr); @@ -201,7 +184,7 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, return ret; } -bool CborConverter::addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& +bool CborConverter::addVerificationToken(Array& array, const VerificationToken& verificationToken) { array.add(verificationToken.challenge); array.add(verificationToken.timestamp); @@ -211,7 +194,7 @@ bool CborConverter::addVerificationToken(Array& array, const ::android::hardware return true; } -bool CborConverter::addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& +bool CborConverter::addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken) { array.add(authToken.challenge); array.add(authToken.userId); @@ -281,7 +264,7 @@ bool CborConverter::getVerificationToken(const std::unique_ptr& item, cons } -bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { +bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec& keyParams) { bool ret = false; std::unique_ptr mapItem(nullptr); getItemAtPos(item, pos, mapItem); @@ -291,7 +274,7 @@ bool CborConverter::getKeyParameters(const std::unique_ptr& item, const ui const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); for (int i = 0; i < mapSize; i++) { - ::android::hardware::keymaster::V4_0::KeyParameter param; + KeyParameter param; if (!getKeyparameter((*map)[i], param)) { return ret; } diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp index b03262d1..e29a5596 100644 --- a/HAL/keymaster/4.1/SocketTransport.cpp +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -20,7 +20,6 @@ #include #include "Transport.h" -/* TODO How to get these two values */ #define PORT 8080 #define IPADDR "10.9.40.24" #define MAX_RECV_BUFFER_SIZE 2048 diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 5cd60584..e128c331 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -17,34 +17,27 @@ #ifndef __CBOR_CONVERTER_H_ #define __CBOR_CONVERTER_H_ -#include + #include -#include -#include -#include -#include #include #include #include #include #include -#define EMPTY(A) *(A*)nullptr - using namespace cppbor; +using ::android::hardware::hidl_vec; using ::android::hardware::keymaster::V4_0::ErrorCode; -using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; using ::android::hardware::keymaster::V4_0::HardwareAuthToken; +using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; using ::android::hardware::keymaster::V4_0::HmacSharingParameters; -using ::android::hardware::keymaster::V4_0::IKeymasterDevice; -using ::android::hardware::keymaster::V4_0::KeyCharacteristics; -using ::android::hardware::keymaster::V4_0::KeyFormat; using ::android::hardware::keymaster::V4_0::KeyParameter; -using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::VerificationToken; +using ::android::hardware::keymaster::V4_0::KeyCharacteristics; using ::android::hardware::keymaster::V4_0::SecurityLevel; +using ::android::hardware::keymaster::V4_0::TagType; using ::android::hardware::keymaster::V4_0::Tag; -using ::android::hardware::keymaster::V4_0::VerificationToken; class CborConverter { @@ -52,29 +45,78 @@ class CborConverter CborConverter() = default; ~CborConverter() = default; + /** + * Parses the input data which is in CBOR format and returns a Tuple of Item pointer, buffer pointer and + * message. + */ ParseResult decodeData(const std::vector cborData); - /* Use this function to get both signed and usinged integers.*/ + /** + * Get the signed/unsigned integer value at a given position from the item pointer. + */ template bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + + /** + * Get the HmacSharingParameters structure value at the given position from the item pointer. + */ bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); + + /** + * Get the Binary string at the given position from the item pointer. + */ bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); + + /** + * Get the HardwareAuthToken value at the given position from the item pointer. + */ bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); - bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams); - bool addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& + + /** + * Get the list of KeyParameters value at the given position from the item pointer. + */ + bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec& keyParams); + + /** + * Adds the the list of KeyParameters values to the Array item. + */ + bool addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams); - bool addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& + + /** + * Add HardwareAuthToken value to the Array item. + */ + bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken); + + /** + * Get the VerificationToken value at the given position from the item pointer. + */ bool getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& token); + + /** + * Get the KeyCharacteristics value at the given position from the item pointer. + */ bool getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, - ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics); + KeyCharacteristics& keyCharacteristics); + + /** + * Get the list of binary arrays at the given position from the item pointer. + */ bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data); - bool addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& + + /** + * Add VerificationToken value to the Array item. + */ + bool addVerificationToken(Array& array, const VerificationToken& verificationToken); - template) || + /** + * Get the ErrorCode value at the give position from the item pointer. + */ + template) || (std::is_same_v)>> inline bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, T& errorCode) { bool ret = false; @@ -88,13 +130,21 @@ class CborConverter return ret; } - - - private: + /** + * Get the type of the Item pointer. + */ inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } + + /** + * Construct Keyparameter structure from the pair of key and value. + */ bool getKeyparameter(const std::pair&, const std::unique_ptr&> pair, KeyParameter& keyParam); + + /** + * Get the sub item pointer from the root item pointer at the given position. + */ inline void getItemAtPos(const std::unique_ptr& item, const uint32_t pos, std::unique_ptr& subItem) { Array* arr = nullptr; diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 6bb62387..669bbeac 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -18,7 +18,6 @@ #ifndef KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ #define KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ -#include #include #include #include @@ -56,7 +55,7 @@ class JavacardKeymaster4Device : public IKeymasterDevice { JavacardKeymaster4Device() { pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( android::base::GetBoolProperty("ro.kernel.qemu", false))); - assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); + pTransportFactory->openConnection(); } virtual ~JavacardKeymaster4Device() {} diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h index aadb3f00..7b0c1e2e 100644 --- a/HAL/keymaster/include/Transport.h +++ b/HAL/keymaster/include/Transport.h @@ -19,23 +19,59 @@ namespace se_transport { +/** + * ITransport is an abstract interface with a set of virtual methods that allow communication between the keymaster + * HAL and the secure element. + */ class ITransport { public: virtual ~ITransport(){} + + /** + * Opens connection. + */ virtual bool openConnection() = 0; + /** + * Send data over communication channel and receives data back from the remote end. + */ virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) = 0; + /** + * Closes the connection. + */ virtual bool closeConnection() = 0; + /** + * Returns the state of the connection status. Returns true if the connection is active, false if connection is + * broken. + */ virtual bool isConnected() = 0; }; +/** + * OmapiTransport is derived from ITransport. This class gets the OMAPI service binder instance and uses IPC to + * communicate with OMAPI service. OMAPI inturn communicates with hardware via ISecureElement. + */ class OmapiTransport : public ITransport { public: + /** + * Gets the binder instance of ISEService, gets the reader corresponding to secure element, establishes a session + * and opens a basic channel. + */ bool openConnection() override; - virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + /** + * Transmists the data over the opened basic channel and receives the data back. + */ + bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + /** + * Closes the connection. + */ bool closeConnection() override; + /** + * Returns the state of the connection status. Returns true if the connection is active, false if connection is + * broken. + */ bool isConnected() override; }; @@ -43,11 +79,27 @@ class OmapiTransport : public ITransport { class SocketTransport : public ITransport { public: + /** + * Creates a socket instance and connects to the provided server IP and port. + */ bool openConnection() override; - virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + /** + * Sends data over socket and receives data back. + */ + bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + /** + * Closes the connection. + */ bool closeConnection() override; + /** + * Returns the state of the connection status. Returns true if the connection is active, false if connection is + * broken. + */ bool isConnected() override; private: + /** + * Socket instance. + */ int mSocket; }; diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h index 2e01e66b..b09e3ba9 100644 --- a/HAL/keymaster/include/TransportFactory.h +++ b/HAL/keymaster/include/TransportFactory.h @@ -21,6 +21,10 @@ namespace se_transport { +/** + * TransportFactory class decides which transport mechanism to be used to send data to secure element. In case of + * emulator the communication channel is socket and in case of device the communication channel is via OMAPI. + */ class TransportFactory { public: TransportFactory(bool isEmulator) { @@ -32,23 +36,39 @@ class TransportFactory { ~TransportFactory() {} + /** + * Establishes a communication channel with the secure element. + */ inline bool openConnection() { return mTransport->openConnection(); } + /** + * Sends the data to the secure element and also receives back the data. + * This is a blocking call. + */ inline bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { return mTransport->sendData(inData, inLen, output); } + /** + * Close the connection. + */ inline bool closeConnection() { return mTransport->closeConnection(); } + /** + * Returns the connection status of the communication channel. + */ inline bool isConnected() { return mTransport->isConnected(); } private: + /** + * Holds the instance of either OmapiTransport class or SocketTransport class. + */ std::unique_ptr mTransport; }; From 1211db1fac03e34ef30cc6fa43b4dab43aa4bc7b Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 19 May 2020 19:01:24 +0530 Subject: [PATCH 32/58] Fix for ENUM_REP tags while encoding to CBOR Fixed crash issue when we receive cbor data from se. --- HAL/keymaster/4.1/CborConverter.cpp | 13 +++++- .../4.1/JavacardKeymaster4Device.cpp | 44 +++++++++---------- HAL/keymaster/4.1/SocketTransport.cpp | 22 ++++++++-- HAL/keymaster/include/Transport.h | 3 ++ 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index de2b0b75..c8fceb52 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -19,16 +19,19 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams) { Map map; + std::map> enum_repetition; for(size_t i = 0; i < keyParams.size(); i++) { KeyParameter param = keyParams[i]; TagType tagType = static_cast(param.tag & (0xF << 28)); switch(tagType) { case TagType::ENUM: - case TagType::ENUM_REP: case TagType::UINT: - case TagType::UINT_REP: map.add(static_cast(param.tag), param.f.integer); break; + //case TagType::UINT_REP: + case TagType::ENUM_REP: + enum_repetition[static_cast(param.tag)].push_back(static_cast(param.f.integer)); + break; case TagType::ULONG: case TagType::ULONG_REP: map.add(static_cast(param.tag), param.f.longInteger); @@ -48,6 +51,12 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl break; } } + if(0 < enum_repetition.size()) { + for( auto const& [key, val] : enum_repetition ) { + Bstr bstr(val); + map.add(key, std::move(bstr)); + } + } array.add(std::move(map)); return true; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 0c28f055..b3dd66eb 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -112,7 +112,7 @@ std::vector& response) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } - if(APDU_RESP_STATUS_OK != getStatus(response)) { + if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { return (ErrorCode::UNKNOWN_ERROR); } return (ErrorCode::OK);//success @@ -132,7 +132,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ ErrorCode ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); - if(ret == ErrorCode::OK) { + if((ret == ErrorCode::OK) && (resp.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector temp; @@ -159,7 +159,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa errorCode = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborData.begin(), cborData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Error Code @@ -194,7 +194,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -224,7 +224,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan errorCode = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -249,7 +249,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -273,7 +273,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& errorCode = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -305,7 +305,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -340,7 +340,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO keyBlob is BSTR */ @@ -372,7 +372,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -400,7 +400,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl errorCode = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO Keyblobc - BSTR()*/ @@ -430,7 +430,7 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA errorCode = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -456,7 +456,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl errorCode = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { /* TODO Keyblob BSTR(ARRAY) */ @@ -483,7 +483,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -502,7 +502,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -521,7 +521,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { errorCode = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -554,7 +554,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< errorCode = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -588,7 +588,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi errorCode = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -624,7 +624,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi errorCode = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { std::vector bstr; @@ -652,7 +652,7 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { errorCode = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -678,7 +678,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device /* TODO DeviceLocked command handled inside HAL */ ErrorCode ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); - if(ret == ErrorCode::OK) { + if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode @@ -697,7 +697,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device ErrorCode ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); - if(ret == ErrorCode::OK) { + if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. if (item != nullptr) { cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp index e29a5596..0dba18f9 100644 --- a/HAL/keymaster/4.1/SocketTransport.cpp +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -28,10 +28,9 @@ namespace se_transport { bool SocketTransport::openConnection() { struct sockaddr_in serv_addr; - if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - LOG(ERROR) << "Socket creation failed"; + LOG(ERROR) << "Socket creation failed" << " Error: "<& output) { uint8_t buffer[MAX_RECV_BUFFER_SIZE]; + int count = 1; + while(!socketStatus && count++ < 5 ) { + sleep(1); + LOG(ERROR) << "Trying to open socket connection... count: " << count; + openConnection(); + } + + if(count >= 5) { + LOG(ERROR) << "Failed to open socket connection"; + return false; + } + if (0 > send(mSocket, inData, inLen , 0 )) { LOG(ERROR) << "Failed to send data over socket."; return false; @@ -71,12 +84,13 @@ bool SocketTransport::sendData(const uint8_t* inData, const size_t inLen, std::v bool SocketTransport::closeConnection() { close(mSocket); + socketStatus = false; return true; } bool SocketTransport::isConnected() { //TODO - return true; + return socketStatus; } } diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h index 7b0c1e2e..4c230b0a 100644 --- a/HAL/keymaster/include/Transport.h +++ b/HAL/keymaster/include/Transport.h @@ -79,6 +79,8 @@ class OmapiTransport : public ITransport { class SocketTransport : public ITransport { public: + SocketTransport() : socketStatus(false) { + } /** * Creates a socket instance and connects to the provided server IP and port. */ @@ -101,6 +103,7 @@ class SocketTransport : public ITransport { * Socket instance. */ int mSocket; + bool socketStatus; }; From 71032c0e173ef55b584886c1ac0947e11146fb54 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Thu, 21 May 2020 16:46:03 +0530 Subject: [PATCH 33/58] Import PKCS8 key using software key master and then feed as RAW format to Javacard keymaster. --- HAL/keymaster/4.1/CborConverter.cpp | 6 +- .../4.1/JavacardKeymaster4Device.cpp | 133 +++++++++++++++++- HAL/keymaster/Android.bp | 4 +- .../include/JavacardKeymaster4Device.h | 18 +-- 4 files changed, 150 insertions(+), 11 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index c8fceb52..5f3595e4 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -16,6 +16,7 @@ */ #include +#include bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams) { Map map; @@ -40,7 +41,10 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl map.add(static_cast(param.tag), param.f.dateTime); break; case TagType::BOOL: - map.add(static_cast(param.tag), param.f.boolValue); + { + uint8_t boolValue = static_cast(param.f.boolValue); + map.add(static_cast(param.tag), boolValue); + } break; case TagType::BIGNUM: case TagType::BYTES: diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index b3dd66eb..c6561d5e 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -21,6 +21,10 @@ #include #include #include +#include +#include +#include + #include //#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" @@ -34,6 +38,7 @@ namespace keymaster { namespace V4_1 { namespace javacard { +constexpr size_t kOperationTableSize = 16; enum class Instruction { INS_GENERATE_KEY_CMD = 0x10, @@ -60,6 +65,98 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x25 }; +inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { + return static_cast(value); +} + +inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { + return static_cast(value); +} + +inline keymaster_tag_t legacy_enum_conversion(const Tag value) { + return keymaster_tag_t(value); +} + +inline Tag legacy_enum_conversion(const keymaster_tag_t value) { + return Tag(value); +} + +inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { + keymaster_key_param_set_t set; + + set.params = new keymaster_key_param_t[keyParams.size()]; + set.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: + set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + set.params[i] = keymaster_param_bool(tag); + else + set.params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + set.params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: + set.params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + + return set; +} + +class KmParamSet : public keymaster_key_param_set_t { + public: + explicit KmParamSet(const hidl_vec& keyParams) + : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} + 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; } +}; + +JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( + []() -> auto { + auto context = new PureSoftKeymasterContext(); + context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); + return context; + }(), + kOperationTableSize)) { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); +} + +JavacardKeymaster4Device::~JavacardKeymaster4Device() {} + ErrorCode constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { apduOut.push_back(static_cast(APDU_CLS)); //CLS apduOut.push_back(static_cast(ins)); //INS @@ -289,6 +386,40 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& } Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { + keymaster_error_t error; + hidl_vec inKey; + + if (keyFormat == KeyFormat::PKCS8) { + ImportKeyRequest request; + request.key_description.Reinitialize(KmParamSet(keyParams)); + request.key_format = legacy_enum_conversion(keyFormat); + request.SetKeyMaterial(keyData.data(), keyData.size()); + + ImportKeyResponse response; + softKm_->ImportKey(request, &response); + + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + if (response.error == KM_ERROR_OK) { + AuthorizationSet hidden; + error = BuildHiddenAuthorizations(request.key_description, &hidden, softwareRootOfTrust); + if (error == KM_ERROR_OK) { + KeymasterKeyBlob key_material; + DeserializeIntegrityAssuredBlob(KeymasterKeyBlob(response.key_blob), hidden, &key_material, &response.enforced, &response.unenforced); + + inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); + } + } + } else if (keyFormat == KeyFormat::RAW) { + //convert keyData to keyMaterial + inKey = keyData; + } else { + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + _hidl_cb(legacy_enum_conversion(KM_ERROR_UNSUPPORTED_KEY_FORMAT), resultKeyBlob, resultCharacteristics); + return Void(); + } + cppbor::Array array; const uint8_t* pos; std::unique_ptr item; @@ -300,7 +431,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k cborConverter_.addKeyparameters(array, keyParams); array.add(static_cast(keyFormat)); - array.add(std::vector(keyData)); + array.add(std::vector(inKey)); std::vector cborData = array.encode(); errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 65302a74..10bfe5d2 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -30,12 +30,14 @@ cc_library { "libutils", "libhardware", "libhidlbase", + "libsoftkeymasterdevice", "libkeymaster_messages", + "libkeymaster_portable", "libcppbor_external", - "omapi_external", "android.hardware.keymaster@4.1", "android.hardware.keymaster@4.0", "libjc_transport", + "libcrypto", ], } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 669bbeac..058812e9 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -24,6 +24,9 @@ #include #include "CborConverter.h" #include "TransportFactory.h" +#include +#include +#include namespace keymaster { namespace V4_1 { @@ -46,19 +49,15 @@ using ::android::hardware::keymaster::V4_0::OperationHandle; using ::android::hardware::keymaster::V4_0::SecurityLevel; using ::android::hardware::keymaster::V4_0::VerificationToken; using ::android::hardware::keymaster::V4_1::IKeymasterDevice; -using ::android::hardware::keymaster::V4_1::Tag; +using ::android::hardware::keymaster::V4_0::Tag; using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode; class JavacardKeymaster4Device : public IKeymasterDevice { public: - JavacardKeymaster4Device() { - pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( - android::base::GetBoolProperty("ro.kernel.qemu", false))); - pTransportFactory->openConnection(); - } - - virtual ~JavacardKeymaster4Device() {} + + JavacardKeymaster4Device(); + virtual ~JavacardKeymaster4Device(); // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; @@ -88,6 +87,9 @@ class JavacardKeymaster4Device : public IKeymasterDevice { protected: CborConverter cborConverter_; std::unique_ptr pTransportFactory; + +private: + std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; }; } // namespace javacard From 8c443f8cee66cd82c73206c6c82b76b475ea9f83 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 21 May 2020 19:53:58 +0530 Subject: [PATCH 34/58] Identation for importKey function Added UINT ULONG repetetion logic in CborConverter class for KeyParameters --- HAL/keymaster/4.1/CborConverter.cpp | 20 +++++++++---- .../4.1/JavacardKeymaster4Device.cpp | 28 +++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 5f3595e4..ab7a119e 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -21,6 +21,7 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams) { Map map; std::map> enum_repetition; + std::map> uint_repetition; for(size_t i = 0; i < keyParams.size(); i++) { KeyParameter param = keyParams[i]; TagType tagType = static_cast(param.tag & (0xF << 28)); @@ -29,22 +30,23 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl case TagType::UINT: map.add(static_cast(param.tag), param.f.integer); break; - //case TagType::UINT_REP: + case TagType::UINT_REP: + uint_repetition[static_cast(param.tag)].push_back(static_cast(param.f.integer)); + break; case TagType::ENUM_REP: enum_repetition[static_cast(param.tag)].push_back(static_cast(param.f.integer)); break; case TagType::ULONG: - case TagType::ULONG_REP: map.add(static_cast(param.tag), param.f.longInteger); break; + case TagType::ULONG_REP: + uint_repetition[static_cast(param.tag)].push_back(param.f.longinteger); + break; case TagType::DATE: map.add(static_cast(param.tag), param.f.dateTime); break; case TagType::BOOL: - { - uint8_t boolValue = static_cast(param.f.boolValue); - map.add(static_cast(param.tag), boolValue); - } + map.add(static_cast(param.tag), static_cast(param.f.boolValue)); break; case TagType::BIGNUM: case TagType::BYTES: @@ -61,6 +63,12 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl map.add(key, std::move(bstr)); } } + if(0 < uint_repetition.size()) { + for( auto const& [key, val] : uint_repetition ) { + Bstr bstr(val); + map.add(key, std::move(bstr)); + } + } array.add(std::move(map)); return true; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index c6561d5e..929c161e 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -388,18 +388,18 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { keymaster_error_t error; hidl_vec inKey; - + if (keyFormat == KeyFormat::PKCS8) { - ImportKeyRequest request; - request.key_description.Reinitialize(KmParamSet(keyParams)); - request.key_format = legacy_enum_conversion(keyFormat); - request.SetKeyMaterial(keyData.data(), keyData.size()); + ImportKeyRequest request; + request.key_description.Reinitialize(KmParamSet(keyParams)); + request.key_format = legacy_enum_conversion(keyFormat); + request.SetKeyMaterial(keyData.data(), keyData.size()); - ImportKeyResponse response; - softKm_->ImportKey(request, &response); + ImportKeyResponse response; + softKm_->ImportKey(request, &response); - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; if (response.error == KM_ERROR_OK) { AuthorizationSet hidden; error = BuildHiddenAuthorizations(request.key_description, &hidden, softwareRootOfTrust); @@ -414,12 +414,12 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k //convert keyData to keyMaterial inKey = keyData; } else { - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - _hidl_cb(legacy_enum_conversion(KM_ERROR_UNSUPPORTED_KEY_FORMAT), resultKeyBlob, resultCharacteristics); - return Void(); + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + _hidl_cb(legacy_enum_conversion(KM_ERROR_UNSUPPORTED_KEY_FORMAT), resultKeyBlob, resultCharacteristics); + return Void(); } - + cppbor::Array array; const uint8_t* pos; std::unique_ptr item; From 5b28518fd1ce1f3d0cbd80b85557b8cca138099d Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 21 May 2020 20:39:57 +0530 Subject: [PATCH 35/58] Added logic for uint and ulong repetitions --- HAL/keymaster/4.1/CborConverter.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index ab7a119e..ad56f9ef 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -21,7 +21,7 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec& keyParams) { Map map; std::map> enum_repetition; - std::map> uint_repetition; + std::map uint_repetition; for(size_t i = 0; i < keyParams.size(); i++) { KeyParameter param = keyParams[i]; TagType tagType = static_cast(param.tag & (0xF << 28)); @@ -31,7 +31,7 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl map.add(static_cast(param.tag), param.f.integer); break; case TagType::UINT_REP: - uint_repetition[static_cast(param.tag)].push_back(static_cast(param.f.integer)); + uint_repetition[static_cast(param.tag)].add(param.f.integer); break; case TagType::ENUM_REP: enum_repetition[static_cast(param.tag)].push_back(static_cast(param.f.integer)); @@ -40,7 +40,7 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl map.add(static_cast(param.tag), param.f.longInteger); break; case TagType::ULONG_REP: - uint_repetition[static_cast(param.tag)].push_back(param.f.longinteger); + uint_repetition[static_cast(param.tag)].add(param.f.longInteger); break; case TagType::DATE: map.add(static_cast(param.tag), param.f.dateTime); @@ -64,9 +64,8 @@ bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl } } if(0 < uint_repetition.size()) { - for( auto const& [key, val] : uint_repetition ) { - Bstr bstr(val); - map.add(key, std::move(bstr)); + for( auto & [key, val] : uint_repetition ) { + map.add(key, std::move(val)); } } array.add(std::move(map)); From 6f00169fabc722768125a088940cd4d5f449041e Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sat, 23 May 2020 18:47:23 +0530 Subject: [PATCH 36/58] Fixed issue with parsing KeyCharacteristics. Made parsing logic common for all the APIs --- HAL/keymaster/4.1/CborConverter.cpp | 168 +++++++--- .../4.1/JavacardKeymaster4Device.cpp | 299 ++++++++---------- HAL/keymaster/include/CborConverter.h | 64 +++- 3 files changed, 306 insertions(+), 225 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index ad56f9ef..d19520b2 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -76,7 +76,6 @@ bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, con KeyCharacteristics& keyCharacteristics) { bool ret = false; std::unique_ptr arrayItem(nullptr); - getItemAtPos(item, pos, arrayItem); if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) return ret; @@ -93,54 +92,139 @@ bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, con return ret; } -bool CborConverter::getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam) { +bool CborConverter::getKeyParameter(const std::pair&, + const std::unique_ptr&> pair, std::vector& keyParams) { bool ret = false; + uint64_t key; uint64_t value; - //TAG will be always uint32_t - if (!getUint64(pair.first, 0, value)) { + + if(!getUint64(pair.first, key)) { return ret; } - keyParam.tag = static_cast(value); - if (MajorType::UINT == getType(pair.second)) { - TagType tagType = static_cast(keyParam.tag & (0xF << 28)); - switch(tagType) { - case TagType::ENUM: - case TagType::ENUM_REP: - case TagType::UINT: - case TagType::UINT_REP: + /* Get the TagType from the Tag */ + TagType tagType = static_cast(key & (0xF << 28)); + switch(tagType) { + case TagType::ENUM_REP: + { + /* ENUM_REP contains values encoded in a Binary string */ + const Bstr* bstr = pair.second.get()->asBstr(); + if(bstr == nullptr) return ret; + for (auto bchar : bstr->value()) { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + keyParam.f.integer = bchar; + keyParams.push_back(std::move(keyParam)); + } + return true; + } + break; + case TagType::ENUM: + case TagType::UINT: + { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + if(!getUint64(pair.second, value)) { + return ret; + } keyParam.f.integer = static_cast(value); - break; - case TagType::ULONG: - case TagType::ULONG_REP: - keyParam.f.longInteger = static_cast(value); - break; - case TagType::DATE: - keyParam.f.dateTime = static_cast(value); - break; - case TagType::BOOL: + keyParams.push_back(std::move(keyParam)); + return true; + } + break; + case TagType::ULONG: + { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + if(!getUint64(pair.second, value)) { + return ret; + } + keyParam.f.longInteger = value; + keyParams.push_back(std::move(keyParam)); + return true; + } + break; + case TagType::UINT_REP: + { + /* UINT_REP contains values encoded in a Array */ + Array* array = const_cast(pair.second.get()->asArray()); + if(array == nullptr) return ret; + for(int i = 0; i < array->size(); i++) { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + std::unique_ptr item = std::move((*array)[i]); + if(!getUint64(item, value)) { + return ret; + } + keyParam.f.integer = static_cast(value); + keyParams.push_back(std::move(keyParam)); + + } + return true; + } + break; + case TagType::ULONG_REP: + { + /* ULONG_REP contains values encoded in a Array */ + Array* array = const_cast(pair.second.get()->asArray()); + if(array == nullptr) return ret; + for(int i = 0; i < array->size(); i++) { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + std::unique_ptr item = std::move((*array)[i]); + if(!getUint64(item, keyParam.f.longInteger)) { + return ret; + } + keyParams.push_back(std::move(keyParam)); + + } + return true; + } + break; + case TagType::DATE: + { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + if(!getUint64(pair.second, value)) { + return ret; + } + keyParam.f.dateTime = value; + keyParams.push_back(std::move(keyParam)); + return true; + } + break; + case TagType::BOOL: + { + KeyParameter keyParam; + keyParam.tag = static_cast(key); + if(!getUint64(pair.second, value)) { + return ret; + } keyParam.f.boolValue = static_cast(value); - break; - default: - /* Invalid skip */ - break; - } - } - else if (MajorType::BSTR == getType(pair.second)) { - std::vector blob; - if (!getBinaryArray(pair.second, 0, blob)) { - return ret; - } - keyParam.blob.setToExternal(blob.data(), blob.size()); + keyParams.push_back(std::move(keyParam)); + return true; + } + break; + case TagType::BYTES: + { + std::vector blob; + KeyParameter keyParam; + keyParam.tag = static_cast(key); + if(!getBinaryArray(pair.second, 0, blob)) { + return ret; + } + keyParam.blob.setToExternal(blob.data(), blob.size()); + keyParams.push_back(std::move(keyParam)); + return true; + } + break; + default: + /* Invalid skip */ + break; } return ret; } -ParseResult CborConverter::decodeData(const std::vector cborData) { - return parse(cborData); -} - bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { bool ret = false; @@ -287,19 +371,19 @@ bool CborConverter::getVerificationToken(const std::unique_ptr& item, cons bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec& keyParams) { bool ret = false; std::unique_ptr mapItem(nullptr); + std::vector params; getItemAtPos(item, pos, mapItem); if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) return ret; - const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); for (int i = 0; i < mapSize; i++) { - KeyParameter param; - if (!getKeyparameter((*map)[i], param)) { + if (!getKeyParameter((*map)[i], params)) { return ret; } - keyParams[i] = std::move(param); } + keyParams.resize(params.size()); + keyParams = params; ret = true; return ret; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 929c161e..6119abae 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -41,28 +41,28 @@ namespace javacard { constexpr size_t kOperationTableSize = 16; enum class Instruction { - INS_GENERATE_KEY_CMD = 0x10, - INS_IMPORT_KEY_CMD = 0x11, - INS_IMPORT_WRAPPED_KEY_CMD = 0x12, - INS_EXPORT_KEY_CMD = 0x13, - INS_ATTEST_KEY_CMD = 0x14, - INS_UPGRADE_KEY_CMD = 0x15, - INS_DELETE_KEY_CMD = 0x16, - INS_DELETE_ALL_KEYS_CMD = 0x17, - INS_ADD_RNG_ENTROPY_CMD = 0x18, - INS_COMPUTE_SHARED_HMAC_CMD = 0x19, - INS_DESTROY_ATT_IDS_CMD = 0x1A, - INS_VERIFY_AUTHORIZATION_CMD = 0x1B, - INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C, - INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D, - INS_GET_HW_INFO_CMD = 0x1E, - INS_BEGIN_OPERATION_CMD = 0x1F, - INS_UPDATE_OPERATION_CMD = 0x20, - INS_FINISH_OPERATION_CMD = 0x21, - INS_ABORT_OPERATION_CMD = 0x22, - INS_PROVISION_CMD = 0x23, - INS_DEVICE_LOCKED_CMD = 0x24, - INS_EARLY_BOOT_ENDED_CMD = 0x25 + INS_GENERATE_KEY_CMD = 0x10, + INS_IMPORT_KEY_CMD = 0x11, + INS_IMPORT_WRAPPED_KEY_CMD = 0x12, + INS_EXPORT_KEY_CMD = 0x13, + INS_ATTEST_KEY_CMD = 0x14, + INS_UPGRADE_KEY_CMD = 0x15, + INS_DELETE_KEY_CMD = 0x16, + INS_DELETE_ALL_KEYS_CMD = 0x17, + INS_ADD_RNG_ENTROPY_CMD = 0x18, + INS_COMPUTE_SHARED_HMAC_CMD = 0x19, + INS_DESTROY_ATT_IDS_CMD = 0x1A, + INS_VERIFY_AUTHORIZATION_CMD = 0x1B, + INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C, + INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D, + INS_GET_HW_INFO_CMD = 0x1E, + INS_BEGIN_OPERATION_CMD = 0x1F, + INS_UPDATE_OPERATION_CMD = 0x20, + INS_FINISH_OPERATION_CMD = 0x21, + INS_ABORT_OPERATION_CMD = 0x22, + INS_PROVISION_CMD = 0x23, + INS_DEVICE_LOCKED_CMD = 0x24, + INS_EARLY_BOOT_ENDED_CMD = 0x25 }; inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { @@ -94,37 +94,37 @@ keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyPara 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: - set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); - break; - case KM_UINT: - case KM_UINT_REP: - set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); - break; - case KM_ULONG: - case KM_ULONG_REP: - set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); - break; - case KM_DATE: - set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); - break; - case KM_BOOL: - if (keyParams[i].f.boolValue) - set.params[i] = keymaster_param_bool(tag); - else + case KM_ENUM: + case KM_ENUM_REP: + set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + set.params[i] = keymaster_param_bool(tag); + else + set.params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + set.params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: set.params[i].tag = KM_TAG_INVALID; - break; - case KM_BIGNUM: - case KM_BYTES: - set.params[i] = - keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); - break; - case KM_INVALID: - default: - set.params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; + /* just skip */ + break; } } @@ -132,27 +132,27 @@ keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyPara } class KmParamSet : public keymaster_key_param_set_t { - public: - explicit KmParamSet(const hidl_vec& keyParams) - : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} - 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; } + public: + explicit KmParamSet(const hidl_vec& keyParams) + : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} + 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; } }; JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( - []() -> auto { - auto context = new PureSoftKeymasterContext(); - context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); - return context; - }(), - kOperationTableSize)) { - pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( - android::base::GetBoolProperty("ro.kernel.qemu", false))); - assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); + []() -> auto { + auto context = new PureSoftKeymasterContext(); + context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); + return context; + }(), + kOperationTableSize)) { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); } JavacardKeymaster4Device::~JavacardKeymaster4Device() {} @@ -220,9 +220,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); std::vector resp; std::vector input; - const uint8_t* pos; std::unique_ptr item; - std::string message; uint64_t securityLevel = static_cast(SecurityLevel::STRONGBOX); hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; @@ -230,7 +228,9 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ ErrorCode ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); if((ret == ErrorCode::OK) && (resp.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, ret) = cborConverter_.decodeData(std::vector(resp.begin(), resp.end()-2), + true); if (item != nullptr) { std::vector temp; cborConverter_.getUint64(item, 0, securityLevel); //SecurityLevel @@ -247,19 +247,18 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { std::vector cborData; - const uint8_t* pos; std::vector input; std::unique_ptr item; - std::string message; HmacSharingParameters hmacSharingParameters; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; errorCode = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborData.begin(), cborData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborData.begin(), cborData.end()-2), + true); if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Error Code cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters); //HmacSharingParameters. } } @@ -269,10 +268,8 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec& params, computeSharedHmac_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; std::vector cborOutData; - std::string message; hidl_vec sharingCheck; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -292,10 +289,11 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Error Code cborConverter_.getBinaryArray(item, 1, bstr); sharingCheck.setToExternal(bstr.data(), bstr.size()); } @@ -306,10 +304,8 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec& parametersToVerify, const HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; std::vector cborOutData; - std::string message; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; VerificationToken verificationToken; @@ -322,9 +318,10 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan errorCode = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getVerificationToken(item, 1, verificationToken); } } @@ -333,11 +330,9 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan } Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { - const uint8_t* pos; cppbor::Array array; std::vector cborOutData; std::unique_ptr item; - std::string message; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; /* Convert input data to cbor format */ @@ -347,19 +342,16 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } Return JavacardKeymaster4Device::generateKey(const hidl_vec& keyParams, generateKey_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec keyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -371,10 +363,11 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& errorCode = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode /* TODO keyBlob is BSTR */ cborConverter_.getBinaryArray(item, 1, bstr); keyBlob.setToExternal(bstr.data(), bstr.size()); @@ -421,9 +414,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k } cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec keyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -437,10 +428,11 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode /* TODO keyBlob is BSTR */ cborConverter_.getBinaryArray(item, 1, bstr); keyBlob.setToExternal(bstr.data(), bstr.size()); @@ -453,9 +445,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec keyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -472,11 +462,12 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { /* TODO keyBlob is BSTR */ std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); keyBlob.setToExternal(bstr.data(), bstr.size()); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); @@ -489,9 +480,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; @@ -504,9 +493,10 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics); } } @@ -516,9 +506,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec keyMaterial; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -532,11 +520,12 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl errorCode = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { /* TODO Keyblobc - BSTR()*/ std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); keyMaterial.setToExternal(bstr.data(), bstr.size()); } @@ -547,9 +536,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec keyBlob; std::vector cborOutData; hidl_vec> certChain; @@ -562,9 +549,10 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA errorCode = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getMultiBinaryArray(item, 1, certChain); } } @@ -574,9 +562,7 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec& upgradeParams, upgradeKey_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; hidl_vec upgradedKeyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -588,11 +574,12 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl errorCode = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { /* TODO Keyblob BSTR(ARRAY) */ std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getBinaryArray(item, 1, bstr); upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); } @@ -603,9 +590,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl Return JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -615,18 +600,15 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } Return JavacardKeymaster4Device::deleteAllKeys() { - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -634,18 +616,15 @@ Return JavacardKeymaster4Device::deleteAllKeys() { errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } Return JavacardKeymaster4Device::destroyAttestationIds() { - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -653,10 +632,9 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { errorCode = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } @@ -671,10 +649,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< /* Public key operations are handled here*/ } else { cppbor::Array array; - const uint8_t* pos; std::vector cborOutData; std::unique_ptr item; - std::string message; /* Convert input data to cbor format */ array.add(static_cast(purpose)); @@ -686,9 +662,10 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< errorCode = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getUint64(item, 2, operationHandle); } @@ -700,9 +677,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; hidl_vec outParams; @@ -720,10 +695,11 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi errorCode = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getUint64(item, 1, inputConsumed); cborConverter_.getKeyParameters(item, 2, outParams); cborConverter_.getBinaryArray(item, 3, bstr); @@ -736,9 +712,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; hidl_vec outParams; @@ -756,10 +730,11 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi errorCode = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); if (item != nullptr) { std::vector bstr; - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getBinaryArray(item, 2, bstr); output.setToExternal(bstr.data(), bstr.size()); @@ -771,9 +746,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; @@ -784,10 +757,9 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { errorCode = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } @@ -795,9 +767,7 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) { cppbor::Array array; - const uint8_t* pos; std::unique_ptr item; - std::string message; std::vector cborOutData; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; @@ -810,16 +780,14 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device ErrorCode ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData<::android::hardware::keymaster::V4_1::ErrorCode>(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::earlyBootEnded() { - const uint8_t* pos; std::unique_ptr item; std::string message; std::vector cborOutData; @@ -829,10 +797,9 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device ErrorCode ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { - std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. - if (item != nullptr) { - cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode - } + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData<::android::hardware::keymaster::V4_1::ErrorCode>(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } return errorCode; } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index e128c331..a2ac24ee 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -46,16 +46,39 @@ class CborConverter ~CborConverter() = default; /** - * Parses the input data which is in CBOR format and returns a Tuple of Item pointer, buffer pointer and - * message. - */ - ParseResult decodeData(const std::vector cborData); + * Parses the input data which is in CBOR format and returns a Tuple of Item pointer and the first element in the item pointer. + */ + template + std::tuple, T> decodeData(const std::vector& response, bool + hasErrorCode) { + const uint8_t* pos; + std::unique_ptr item(nullptr); + std::string message; + T errorCode = T::OK; + std::tie(item, pos, message) = parse(response); + if(item != nullptr && hasErrorCode) { + if(MajorType::ARRAY == getType(item)) { + getErrorCode(item, 0, errorCode); + } else if (MajorType::UINT == getType(item)) { + uint64_t err; + getUint64(item, err); + errorCode = static_cast(err); + } + } + return {std::move(item), errorCode}; + } /** * Get the signed/unsigned integer value at a given position from the item pointer. */ template - bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + + /** + * Get the signed/unsigned integer value from the item pointer. + */ + template + bool getUint64(const std::unique_ptr& item, T& value); /** * Get the HmacSharingParameters structure value at the given position from the item pointer. @@ -137,10 +160,11 @@ class CborConverter inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } /** - * Construct Keyparameter structure from the pair of key and value. + * Construct Keyparameter structure from the pair of key and value. If TagType is ENUM_REP the value contains + * binary string. If TagType is UINT_REP or ULONG_REP the value contains Array of unsigned integers. */ - bool getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam); + bool getKeyParameter(const std::pair&, + const std::unique_ptr&> pair, std::vector& keyParam); /** * Get the sub item pointer from the root item pointer at the given position. @@ -160,27 +184,33 @@ class CborConverter }; template -bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { +bool CborConverter::getUint64(const std::unique_ptr& item, T& value) { bool ret = false; - std::unique_ptr intItem(nullptr); - getItemAtPos(item, pos, intItem); - - if ((intItem == nullptr) || - (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || - ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { + if ((item == nullptr) || + (std::is_unsigned::value && (MajorType::UINT != getType(item))) || + ((std::is_signed::value && (MajorType::NINT != getType(item))))) { return ret; } if (std::is_unsigned::value) { - const Uint* uintVal = intItem.get()->asUint(); + const Uint* uintVal = item.get()->asUint(); value = uintVal->value(); } else { - const Nint* nintVal = intItem.get()->asNint(); + const Nint* nintVal = item.get()->asNint(); value = nintVal->value(); } ret = true; return ret; //success } +template +bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { + std::unique_ptr intItem(nullptr); + getItemAtPos(item, pos, intItem); + return getUint64(intItem, value); +} + + + #endif From cdb92dad394c5fc04f087a75abe4dcde1916739f Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 26 May 2020 03:11:18 +0530 Subject: [PATCH 37/58] Optimized getBinaryArray method in CborConverter class. --- HAL/keymaster/4.1/CborConverter.cpp | 37 ++++++++++--------- .../4.1/JavacardKeymaster4Device.cpp | 33 ++++------------- HAL/keymaster/include/CborConverter.h | 7 +++- 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index d19520b2..b54b9337 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -207,13 +207,11 @@ bool CborConverter::getKeyParameter(const std::pair& break; case TagType::BYTES: { - std::vector blob; KeyParameter keyParam; keyParam.tag = static_cast(key); - if(!getBinaryArray(pair.second, 0, blob)) { + if(!getBinaryArray(pair.second, 0, keyParam.blob)) { return ret; } - keyParam.blob.setToExternal(blob.data(), blob.size()); keyParams.push_back(std::move(keyParam)); return true; } @@ -236,19 +234,31 @@ bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const const Array* arr = arrayItem.get()->asArray(); size_t arrSize = arr->size(); for (int i = 0; i < arrSize; i++) { - std::vector innerData; - if (!getBinaryArray(arrayItem, i, innerData)) + if (!getBinaryArray(arrayItem, i, data[i])) return ret; - data[i].setToExternal(innerData.data(), innerData.size()); } ret = true; // success return ret; } -bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { +bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, +::android::hardware::hidl_vec& value) { bool ret = false; std::unique_ptr strItem(nullptr); + getItemAtPos(item, pos, strItem); + if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + return ret; + + const Bstr* bstr = strItem.get()->asBstr(); + value = bstr->value(); + ret = true; + return ret; +} + +bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { + bool ret = false; + std::unique_ptr strItem(nullptr); getItemAtPos(item, pos, strItem); if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) return ret; @@ -261,7 +271,6 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint return ret; } - bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { std::vector paramValue; bool ret = false; @@ -275,10 +284,8 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, return ret; //Seed - if (!getBinaryArray(arrayItem, 0, paramValue)) + if (!getBinaryArray(arrayItem, 0, params.seed)) return ret; - params.seed.setToExternal(paramValue.data(), paramValue.size()); - paramValue.clear(); //nonce if (!getBinaryArray(arrayItem, 1, paramValue)) @@ -311,7 +318,6 @@ bool CborConverter::addHardwareAuthToken(Array& array, const HardwareAuthToken& bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& token) { bool ret = false; - std::vector mac; //challenge if (!getUint64(item, pos, token.challenge)) return ret; @@ -330,9 +336,8 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons if (!getUint64(item, pos+4, token.timestamp)) return ret; //MAC - if (!getBinaryArray(item, pos+5, mac)) + if (!getBinaryArray(item, pos+5, token.mac)) return ret; - token.mac.setToExternal(mac.data(), mac.size()); ret = true; return ret; } @@ -340,7 +345,6 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons bool CborConverter::getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& token) { bool ret = false; - std::vector mac; //challenge if (!getUint64(item, pos, token.challenge)) return ret; @@ -360,9 +364,8 @@ bool CborConverter::getVerificationToken(const std::unique_ptr& item, cons token.securityLevel = static_cast(val); //MAC - if (!getBinaryArray(item, pos+4, mac)) + if (!getBinaryArray(item, pos+4, token.mac)) return ret; - token.mac.setToExternal(mac.data(), mac.size()); ret = true; return ret; diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 6119abae..98b81074 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -367,10 +367,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - std::vector bstr; - /* TODO keyBlob is BSTR */ - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 1, keyBlob); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); } } @@ -432,10 +429,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - std::vector bstr; - /* TODO keyBlob is BSTR */ - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 1, keyBlob); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); } } @@ -466,10 +460,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - /* TODO keyBlob is BSTR */ - std::vector bstr; - cborConverter_.getBinaryArray(item, 1, bstr); - keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 1, keyBlob); cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); } } @@ -524,10 +515,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - /* TODO Keyblobc - BSTR()*/ - std::vector bstr; - cborConverter_.getBinaryArray(item, 1, bstr); - keyMaterial.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 1, keyMaterial); } } _hidl_cb(errorCode, keyMaterial); @@ -578,10 +566,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - /* TODO Keyblob BSTR(ARRAY) */ - std::vector bstr; - cborConverter_.getBinaryArray(item, 1, bstr); - upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 1, upgradedKeyBlob); } } _hidl_cb(errorCode, upgradedKeyBlob); @@ -699,11 +684,9 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - std::vector bstr; cborConverter_.getUint64(item, 1, inputConsumed); cborConverter_.getKeyParameters(item, 2, outParams); - cborConverter_.getBinaryArray(item, 3, bstr); - output.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 3, output); } } _hidl_cb(errorCode, inputConsumed, outParams, output); @@ -734,10 +717,8 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - std::vector bstr; cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getBinaryArray(item, 2, bstr); - output.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getBinaryArray(item, 2, output); } } _hidl_cb(errorCode, outParams, output); diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index a2ac24ee..9f856364 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -88,8 +88,13 @@ class CborConverter /** * Get the Binary string at the given position from the item pointer. */ - bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); + bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value); + /** + * Get the Binary string at the given position from the item pointer. + */ + bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, + ::android::hardware::hidl_vec& value); /** * Get the HardwareAuthToken value at the given position from the item pointer. */ From 3a2de16349420ca8565851201416920269972f69 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 26 May 2020 04:46:20 +0530 Subject: [PATCH 38/58] converted error code to negative number before converting it to ErroCode enum --- HAL/keymaster/include/CborConverter.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 9f856364..bc5cea2f 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -62,7 +62,7 @@ class CborConverter } else if (MajorType::UINT == getType(item)) { uint64_t err; getUint64(item, err); - errorCode = static_cast(err); + errorCode = static_cast(get2sCompliment(static_cast(err))); } } return {std::move(item), errorCode}; @@ -152,13 +152,18 @@ class CborConverter if (!getUint64(item, pos, errorVal)) { return ret; } - errorCode = static_cast(errorVal); + errorCode = static_cast(get2sCompliment(static_cast(errorVal))); ret = true; return ret; } private: + /** + * Returns the negative value of the same number. + */ + inline int32_t get2sCompliment(uint32_t value) { return static_cast(~value+1); } + /** * Get the type of the Item pointer. */ From ad3f8e4b976a47feb6a70bd327d68fc7437e7686 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 26 May 2020 22:00:20 +0530 Subject: [PATCH 39/58] Fixed the crash issue in CborConverter class --- HAL/keymaster/include/CborConverter.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index bc5cea2f..08208ee1 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -54,15 +54,20 @@ class CborConverter const uint8_t* pos; std::unique_ptr item(nullptr); std::string message; - T errorCode = T::OK; + T errorCode = T::UNKNOWN_ERROR; + std::tie(item, pos, message) = parse(response); + if(item != nullptr && hasErrorCode) { if(MajorType::ARRAY == getType(item)) { - getErrorCode(item, 0, errorCode); + if(!getErrorCode(item, 0, errorCode)) + item = nullptr; } else if (MajorType::UINT == getType(item)) { uint64_t err; - getUint64(item, err); - errorCode = static_cast(get2sCompliment(static_cast(err))); + if(getUint64(item, err)) { + errorCode = static_cast(get2sCompliment(static_cast(err))); + } + item = nullptr; /*Already read the errorCode. So no need of sending item to client */ } } return {std::move(item), errorCode}; From 56e18795344ecc22a9c75b7590523d2ff9448443 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Fri, 29 May 2020 18:55:28 +0530 Subject: [PATCH 40/58] Error handling while import key is corrected and started changes for verification operation in begin function --- .../4.1/JavacardKeymaster4Device.cpp | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 98b81074..fa7912b2 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -69,6 +69,10 @@ inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { return static_cast(value); } +inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { + return static_cast(value); +} + inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { return static_cast(value); } @@ -376,7 +380,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& } Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { - keymaster_error_t error; + keymaster_error_t error = KM_ERROR_UNKNOWN_ERROR; hidl_vec inKey; if (keyFormat == KeyFormat::PKCS8) { @@ -390,6 +394,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k KeyCharacteristics resultCharacteristics; hidl_vec resultKeyBlob; + error = response.error; if (response.error == KM_ERROR_OK) { AuthorizationSet hidden; error = BuildHiddenAuthorizations(request.key_description, &hidden, softwareRootOfTrust); @@ -400,6 +405,12 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); } } + if(error != KM_ERROR_OK) { + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + _hidl_cb(legacy_enum_conversion(error), resultKeyBlob, resultCharacteristics); + return Void(); + } } else if (keyFormat == KeyFormat::RAW) { //convert keyData to keyMaterial inKey = keyData; @@ -418,7 +429,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k KeyCharacteristics keyCharacteristics; cborConverter_.addKeyparameters(array, keyParams); - array.add(static_cast(keyFormat)); + array.add(static_cast(KeyFormat::RAW)); //PKCS8 is already converted to RAW array.add(std::vector(inKey)); std::vector cborData = array.encode(); @@ -629,8 +640,26 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< hidl_vec outParams; uint64_t operationHandle = 0; - if (KeyPurpose::ENCRYPT == purpose || - KeyPurpose::VERIFY == purpose) { + if (/*KeyPurpose::ENCRYPT == purpose ||*/ KeyPurpose::VERIFY == purpose) { + + BeginOperationRequest request; + request.purpose = legacy_enum_conversion(purpose); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + request.additional_params.Reinitialize(KmParamSet(inParams)); + + //TODO need to check AUTH_TOKEN will work here? + //hidl_vec hidl_vec_token = authToken2HidlVec(authToken); + //request.additional_params.push_back( + // TAG_AUTH_TOKEN, reinterpret_cast(hidl_vec_token.data()), hidl_vec_token.size()); + + BeginOperationResponse response; + softKm_->BeginOperation(request, &response); + + //hidl_vec resultParams; + //if (response.error == KM_ERROR_OK) resultParams = kmParamSet2Hidl(response.output_params); + + //_hidl_cb(legacy_enum_conversion(response.error), resultParams, response.op_handle); + return Void(); /* Public key operations are handled here*/ } else { cppbor::Array array; From fc69e0d26536308e537797173d0246464612d7aa Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Fri, 5 Jun 2020 16:57:00 +0530 Subject: [PATCH 41/58] Added setBootParams method. Calling it first time before any API gets called. --- .../4.1/JavacardKeymaster4Device.cpp | 105 ++++++++++++------ .../include/JavacardKeymaster4Device.h | 5 + 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 98b81074..9c2e4e5b 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -61,8 +62,9 @@ enum class Instruction { INS_FINISH_OPERATION_CMD = 0x21, INS_ABORT_OPERATION_CMD = 0x22, INS_PROVISION_CMD = 0x23, - INS_DEVICE_LOCKED_CMD = 0x24, - INS_EARLY_BOOT_ENDED_CMD = 0x25 + INS_SET_BOOT_PARAMS_CMD = 0x24, + INS_DEVICE_LOCKED_CMD = 0x25, + INS_EARLY_BOOT_ENDED_CMD = 0x26, }; inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { @@ -149,10 +151,10 @@ JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::A context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); return context; }(), - kOperationTableSize)) { + kOperationTableSize)), setUpBootParams(false) { pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( android::base::GetBoolProperty("ro.kernel.qemu", false))); - assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); + pTransportFactory->openConnection(); } JavacardKeymaster4Device::~JavacardKeymaster4Device() {} @@ -195,15 +197,53 @@ uint16_t getStatus(std::vector& inputData) { return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); } -inline ErrorCode sendData(std::unique_ptr& transport, Instruction ins, std::vector& inData, -std::vector& response) { +/* This method should be called at the time when HAL is initialized for the first time */ +Return setBootParams(std::unique_ptr& transport) { + cppbor::Array array; std::vector apdu; - ErrorCode ret = constructApduMessage(ins, inData, apdu); + std::vector response; + Instruction ins = Instruction::INS_SET_BOOT_PARAMS_CMD; + std::vector verifiedBootKey(32, 0); + std::vector verifiedBootKeyHash(32, 0); + array.add(GetOsVersion()). + add(GetOsPatchlevel()). + /* Verified Boot Key */ + add(verifiedBootKey). + /* Verified Boot Hash */ + add(verifiedBootKeyHash). + /* boot state */ + add(static_cast(KM_VERIFIED_BOOT_UNVERIFIED)). + /* device locked */ + add(0); /* false */ + std::vector cborData = array.encode(); + + ErrorCode ret = constructApduMessage(ins, cborData, apdu); if(ret != ErrorCode::OK) return ret; - //if(!transport->openConnection()) { - // return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); - //} + if(!transport->sendData(apdu.data(), apdu.size(), response)) { + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + } + + if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { + return (ErrorCode::UNKNOWN_ERROR); + } + return ErrorCode::OK; +} + +ErrorCode sendData(JavacardKeymaster4Device *pKeymaster, std::unique_ptr& transport, Instruction ins, std::vector& inData, +std::vector& response) { + ErrorCode ret = ErrorCode::UNKNOWN_ERROR; + std::vector apdu; + + if(!pKeymaster->getBootParamsInitialized()) { + if((ret = setBootParams(transport)) != ErrorCode::OK) { + return ret; + } + pKeymaster->setBootParams(true); + } + + ret = constructApduMessage(ins, inData, apdu); + if(ret != ErrorCode::OK) return ret; if(!transport->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); @@ -225,7 +265,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - ErrorCode ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); + ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); if((ret == ErrorCode::OK) && (resp.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -252,7 +292,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa HmacSharingParameters hmacSharingParameters; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -286,7 +326,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -315,7 +355,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -339,7 +379,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec(data)); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -357,10 +397,11 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; + /* Convert to cbor format */ cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -377,6 +418,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { keymaster_error_t error; + KeymasterKeyBlob key_material; hidl_vec inKey; if (keyFormat == KeyFormat::PKCS8) { @@ -394,7 +436,6 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k AuthorizationSet hidden; error = BuildHiddenAuthorizations(request.key_description, &hidden, softwareRootOfTrust); if (error == KM_ERROR_OK) { - KeymasterKeyBlob key_material; DeserializeIntegrityAssuredBlob(KeymasterKeyBlob(response.key_blob), hidden, &key_material, &response.enforced, &response.unenforced); inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); @@ -422,7 +463,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k array.add(std::vector(inKey)); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -453,7 +494,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -481,7 +522,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(appData)); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -508,7 +549,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl array.add(std::vector(appData)); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -534,7 +575,7 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -559,7 +600,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -582,7 +623,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -598,7 +639,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -614,7 +655,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -644,7 +685,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -677,7 +718,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -710,7 +751,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -735,7 +776,7 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { array.add(operationHandle); std::vector cborData = array.encode(); - errorCode = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -758,7 +799,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - ErrorCode ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -775,7 +816,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - ErrorCode ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 058812e9..6d0be552 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -84,12 +84,17 @@ class JavacardKeymaster4Device : public IKeymasterDevice { Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; Return earlyBootEnded() override; + //Helper methods. + bool getBootParamsInitialized() { return setUpBootParams; } + void setBootParams(bool flag) { setUpBootParams = flag; } + protected: CborConverter cborConverter_; std::unique_ptr pTransportFactory; private: std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; + bool setUpBootParams; }; } // namespace javacard From 60351ae4b580fb51e5b83cb866f1a2615a6f4562 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sat, 13 Jun 2020 03:52:19 +0530 Subject: [PATCH 42/58] Added Operation context class --- .../4.1/JavacardOperationContext.cpp | 197 ++++++++++++++++++ HAL/keymaster/Android.bp | 1 + .../include/JavacardOperationContext.h | 80 +++++++ 3 files changed, 278 insertions(+) create mode 100644 HAL/keymaster/4.1/JavacardOperationContext.cpp create mode 100644 HAL/keymaster/include/JavacardOperationContext.h diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp new file mode 100644 index 00000000..096ace36 --- /dev/null +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -0,0 +1,197 @@ +/* + ** + ** 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 + +#define MAX_ALLOWED_INPUT_SIZE 512 +#define AES_BLOCK_SIZE 16 +#define DES_BLOCK_SIZE 8 + +namespace keymaster { +namespace V4_1 { +namespace javacard { + +enum class Operation { + Update = 0, + Finish = 1 +}; + +struct BufferedData { + uint8_t buf[MAX_BUF_SIZE]; + int buf_len; +}; + +struct OperationData { + OperationInfo info; + BufferedData data; +}; + + +ErrorCode OperationContext::setOperationData(uint64_t operationHandle, OperationInfo& operInfo) { + OperationData data; + data.info = operInfo; + operationTable[operationHandle] = data; + return ErrorCode::OK; +} + +ErrorCode OperationContext::getOperationData(uint64_t operHandle, OperationInfo& operInfo) { + auto itr = operationTable.find(operHandle); + if(itr != operationTable.end()) { + operInfo = itr->second.info; + return ErrorCode::OK; + } + return ErrorCode::INVALID_OPERATION_HANDLE; +} + +ErrorCode OperationContext::clearOperationData(uint64_t operHandle) { + size_t size = operationTable.erase(operHandle); + if(!size) + return ErrorCode::INVALID_OPERATION_HANDLE; + else + return ErrorCode::OK; +} + +ErrorCode OperationContext::update(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb) { + ErrorCode errorCode = ErrorCode::OK; + if (input.size() > MAX_ALLOWED_INPUT_SIZE) { + int noOfChunks = input.size()/MAX_ALLOWED_INPUT_SIZE; + int extraData = input.size()%MAX_ALLOWED_INPUT_SIZE; + for(int i =0 ; i < noOfChunks; i++) { + auto first = input.cbegin() + (i*MAX_ALLOWED_INPUT_SIZE); + auto end = first + MAX_ALLOWED_INPUT_SIZE; + std::vector newInput(first, end); + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, newInput.data(), newInput.size(), + Operation::Update, cb))) { + return errorCode; + } + } + if(extraData > 0) { + std::vector finalInput(input.cend()-extraData, input.cend()); + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, finalInput.data(), finalInput.size(), + Operation::Update, cb))) { + return errorCode; + } + } + } else { + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, input.data(), input.size(), + Operation::Update, cb))) { + return errorCode; + } + } + return errorCode; +} + +ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb) { + ErrorCode errorCode = ErrorCode::OK; + if (input.size() > MAX_ALLOWED_INPUT_SIZE) { + int noOfChunks = input.size()/MAX_ALLOWED_INPUT_SIZE; + int extraData = input.size()%MAX_ALLOWED_INPUT_SIZE; + for(int i =0 ; i < noOfChunks; i++) { + auto first = input.cbegin() + (i*MAX_ALLOWED_INPUT_SIZE); + auto end = first + MAX_ALLOWED_INPUT_SIZE; + std::vector newInput(first, end); + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, newInput.data(), newInput.size(), + Operation::Finish, cb))) { + return errorCode; + } + } + if(extraData > 0) { + std::vector finalInput(input.cend()-extraData, input.cend()); + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, finalInput.data(), finalInput.size(), + Operation::Finish, cb))) { + return errorCode; + } + } + } else { + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, input.data(), input.size(), + Operation::Finish, cb))) { + return errorCode; + } + } + return errorCode; +} + +ErrorCode OperationContext::internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& out) { + int dataToSELen=0; + /*Length of the data consumed from input */ + int inputConsumed=0; + bool dataSendToSE = true; + int blockSize = 0; + BufferedData data = operationTable[operHandle].data; + int bufIndex = data.buf_len; + + if(Algorithm::AES == operationTable[operHandle].info.alg) { + blockSize = AES_BLOCK_SIZE; + } else if(Algorithm::TRIPLE_DES == operationTable[operHandle].info.alg) { + blockSize = DES_BLOCK_SIZE; + } + + if(data.buf_len > 0) { + if(opr == Operation::Finish) { + //Copy the buffer to be send to SE. + for(int i = 0; i < data.buf_len; i++) + { + out.push_back(data.buf[i]); + } + dataToSELen = data.buf_len + input_len; + } else { + if (data.buf_len + input_len >= blockSize) { + dataToSELen = data.buf_len + input_len; + //Copy the buffer to be send to SE. + for(int i = 0; i < data.buf_len; i++) + { + out.push_back(data.buf[i]); + } + } else { + dataSendToSE = false; + } + } + } else { + dataToSELen = input_len; + } + + if(dataSendToSE) { + if(opr == Operation::Update) { + dataToSELen = (dataToSELen/blockSize) * blockSize; + } + inputConsumed = dataToSELen - data.buf_len; + + //Copy the buffer to be send to SE. + for(int i = 0; i < inputConsumed; i++) + { + out.push_back(input[i]); + } + + /* All the data is consumed so clear buffer */ + if(data.buf_len != 0) { + memset(data.buf, 0x00, sizeof(data.buf)); + bufIndex = data.buf_len = 0; + } + } + + //Store the remaining buffer for later use. + data.buf_len += (input_len - inputConsumed); + for(int i = 0; i < (input_len - inputConsumed); i++) + { + data.buf[bufIndex+i] = input[inputConsumed+i]; + } + return ErrorCode::OK; +} + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 10bfe5d2..b3a21fa0 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -18,6 +18,7 @@ cc_library { srcs: [ "4.1/JavacardKeymaster4Device.cpp", "4.1/CborConverter.cpp", + "4.1/JavacardOperationContext.cpp", ], local_include_dirs: [ "include", diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h new file mode 100644 index 00000000..e63b5011 --- /dev/null +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -0,0 +1,80 @@ +/* + ** + ** 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. + */ + +#ifndef KEYMASTER_V4_1_JAVACARD_OPERATIONCONTEXT_H_ +#define KEYMASTER_V4_1_JAVACARD_OPERATIONCONTEXT_H_ + +#include +#include + +#define MAX_BUF_SIZE 32 + +namespace keymaster { +namespace V4_1 { +namespace javacard { + +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::Algorithm; +using ::android::hardware::keymaster::V4_0::KeyPurpose; + +using sendDataToSE_cb = std::function& data)>; + +enum class Operation; +struct OperationData; + +struct OperationInfo { + Algorithm alg; + KeyPurpose purpose; +}; + +class OperationContext { + +public: + OperationContext(){} + ~OperationContext() {} + ErrorCode setOperationData(uint64_t operationHandle, OperationInfo& oeprInfo); + ErrorCode getOperationData(uint64_t operHandle, OperationInfo& operInfo); + ErrorCode clearOperationData(uint64_t operationHandle); + ErrorCode update(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); + ErrorCode finish(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); + +private: + std::map operationTable; + ErrorCode internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& + out); + inline ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, + sendDataToSE_cb cb) { + ErrorCode errorCode = ErrorCode::OK; + std::vector out; + if(ErrorCode::OK != (errorCode = internalUpdate(operHandle, data, len, + opr, out))) { + return errorCode; + } + if(ErrorCode::OK != (errorCode = cb(out))) { + return errorCode; + } + return errorCode; + } + + +}; + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster + +#endif // KEYMASTER_V4_1_JAVACARD_OPERATIONCONTEXT_H_ From 3bedbe4dd83151891b435dc72bc751f96d4b6ea6 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Mon, 15 Jun 2020 00:33:47 +0530 Subject: [PATCH 43/58] Added java_card_soft_keymaster_context extending pure soft keymaster context to support public key operations in JavaCardKeymaster HAL. It is used in public key operations such as RSA encryption, signature verification, exporting public key and also used for decoding pkcs8 key for importing. --- .../4.1/JavacardKeymaster4Device.cpp | 245 +++++++++---- .../4.1/java_card_soft_keymaster_context.cpp | 334 ++++++++++++++++++ HAL/keymaster/Android.bp | 1 + .../java_card_soft_keymaster_context.h | 68 ++++ 4 files changed, 570 insertions(+), 78 deletions(-) create mode 100644 HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp create mode 100644 HAL/keymaster/include/java_card_soft_keymaster_context.h diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 13342f94..11bcd8b9 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -27,6 +27,7 @@ #include #include +#include //#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" //#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" @@ -149,9 +150,59 @@ class KmParamSet : public keymaster_key_param_set_t { ~KmParamSet() { delete[] params; } }; +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; +} + +inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { + hidl_vec result; + result.setToExternal(const_cast(buf.peek_read()), buf.available_read()); + return result; +} + JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( []() -> auto { - auto context = new PureSoftKeymasterContext(); + auto context = new JavaCardSoftKeymasterContext(); context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); return context; }(), @@ -423,6 +474,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { keymaster_error_t error = KM_ERROR_UNKNOWN_ERROR; hidl_vec inKey; + KeymasterKeyBlob key_material; if (keyFormat == KeyFormat::PKCS8) { ImportKeyRequest request; @@ -437,13 +489,8 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k hidl_vec resultKeyBlob; error = response.error; if (response.error == KM_ERROR_OK) { - AuthorizationSet hidden; - error = BuildHiddenAuthorizations(request.key_description, &hidden, softwareRootOfTrust); - if (error == KM_ERROR_OK) { - DeserializeIntegrityAssuredBlob(KeymasterKeyBlob(response.key_blob), hidden, &key_material, &response.enforced, &response.unenforced); - - inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); - } + key_material = KeymasterKeyBlob(response.key_blob); + inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); } if(error != KM_ERROR_OK) { KeyCharacteristics resultCharacteristics; @@ -546,14 +593,30 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { +Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const hidl_vec& keyBlob, const hidl_vec& /*clientId*/, const hidl_vec& /*appData*/, exportKey_cb _hidl_cb) { + + ExportKeyRequest request; + request.key_format = legacy_enum_conversion(exportFormat); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + //addClientAndAppData(clientId, appData, &request.additional_params); + + ExportKeyResponse response; + softKm_->ExportKey(request, &response); + + hidl_vec resultKeyBlob; + if (response.error == KM_ERROR_OK) { + resultKeyBlob.setToExternal(response.key_data, response.key_data_length); + } + _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob); + return Void(); +/* cppbor::Array array; std::unique_ptr item; hidl_vec keyMaterial; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - array.add(static_cast(keyFormat)); + array.add(static_cast(exportFormat)); array.add(std::vector(keyBlob)); array.add(std::vector(clientId)); array.add(std::vector(appData)); @@ -570,7 +633,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl } } _hidl_cb(errorCode, keyMaterial); - return Void(); + return Void();*/ } Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { @@ -680,49 +743,45 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< hidl_vec outParams; uint64_t operationHandle = 0; - if (/*KeyPurpose::ENCRYPT == purpose ||*/ KeyPurpose::VERIFY == purpose) { - + if (KeyPurpose::ENCRYPT == purpose || KeyPurpose::VERIFY == purpose) { BeginOperationRequest request; request.purpose = legacy_enum_conversion(purpose); request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); request.additional_params.Reinitialize(KmParamSet(inParams)); - //TODO need to check AUTH_TOKEN will work here? - //hidl_vec hidl_vec_token = authToken2HidlVec(authToken); - //request.additional_params.push_back( - // TAG_AUTH_TOKEN, reinterpret_cast(hidl_vec_token.data()), hidl_vec_token.size()); - BeginOperationResponse response; softKm_->BeginOperation(request, &response); - //hidl_vec resultParams; - //if (response.error == KM_ERROR_OK) resultParams = kmParamSet2Hidl(response.output_params); + hidl_vec resultParams; + if (response.error == KM_ERROR_OK) { + resultParams = kmParamSet2Hidl(response.output_params); + } + if (response.error != KM_ERROR_INCOMPATIBLE_ALGORITHM) { /*Incompatible algorithm could be handled by JavaCard*/ + _hidl_cb(legacy_enum_conversion(response.error), resultParams, response.op_handle); + return Void(); + } + } - //_hidl_cb(legacy_enum_conversion(response.error), resultParams, response.op_handle); - return Void(); - /* Public key operations are handled here*/ - } else { - cppbor::Array array; - std::vector cborOutData; - std::unique_ptr item; + cppbor::Array array; + std::vector cborOutData; + std::unique_ptr item; - /* Convert input data to cbor format */ - array.add(static_cast(purpose)); - array.add(std::vector(keyBlob)); - cborConverter_.addKeyparameters(array, inParams); - cborConverter_.addHardwareAuthToken(array, authToken); - std::vector cborData = array.encode(); + /* Convert input data to cbor format */ + array.add(static_cast(purpose)); + array.add(std::vector(keyBlob)); + cborConverter_.addKeyparameters(array, inParams); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getUint64(item, 2, operationHandle); - } + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getUint64(item, 2, operationHandle); } } _hidl_cb(errorCode, outParams, operationHandle); @@ -730,32 +789,47 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< } Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - hidl_vec outParams; + UpdateOperationRequest request; + request.op_handle = operationHandle; + request.input.Reinitialize(input.data(), input.size()); + request.additional_params.Reinitialize(KmParamSet(inParams)); + + UpdateOperationResponse response; + softKm_->UpdateOperation(request, &response); + uint32_t inputConsumed = 0; + hidl_vec outParams; hidl_vec output; + errorCode = legacy_enum_conversion(response.error); + if (response.error == KM_ERROR_OK) { + inputConsumed = response.input_consumed; + outParams = kmParamSet2Hidl(response.output_params); + output = kmBuffer2hidlVec(response.output); + } else if(response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; - /* Convert input data to cbor format */ - array.add(operationHandle); - cborConverter_.addKeyparameters(array, inParams); - array.add(std::vector(input)); - cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); - std::vector cborData = array.encode(); + // Convert input data to cbor format + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getUint64(item, 1, inputConsumed); - cborConverter_.getKeyParameters(item, 2, outParams); - cborConverter_.getBinaryArray(item, 3, output); + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + cborConverter_.getUint64(item, 1, inputConsumed); + cborConverter_.getKeyParameters(item, 2, outParams); + cborConverter_.getBinaryArray(item, 3, output); + } } } _hidl_cb(errorCode, inputConsumed, outParams, output); @@ -763,31 +837,46 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi } Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + FinishOperationRequest request; + request.op_handle = operationHandle; + request.input.Reinitialize(input.data(), input.size()); + request.signature.Reinitialize(signature.data(), signature.size()); + request.additional_params.Reinitialize(KmParamSet(inParams)); + + FinishOperationResponse response; + softKm_->FinishOperation(request, &response); + hidl_vec outParams; hidl_vec output; + errorCode = legacy_enum_conversion(response.error); + if (response.error == KM_ERROR_OK) { + outParams = kmParamSet2Hidl(response.output_params); + output = kmBuffer2hidlVec(response.output); + } else if (response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; - /* Convert input data to cbor format */ - array.add(operationHandle); - cborConverter_.addKeyparameters(array, inParams); - array.add(std::vector(input)); - array.add(std::vector(signature)); - cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); - std::vector cborData = array.encode(); + // Convert input data to cbor format + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + array.add(std::vector(signature)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); errorCode = sendData(this, pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getBinaryArray(item, 2, output); + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getBinaryArray(item, 2, output); + } } } _hidl_cb(errorCode, outParams, output); diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp new file mode 100644 index 00000000..76731d5d --- /dev/null +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -0,0 +1,334 @@ +/* + * Copyright 2015 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +using std::unique_ptr; + +namespace keymaster { + +JavaCardSoftKeymasterContext::JavaCardSoftKeymasterContext(keymaster_security_level_t security_level) + : PureSoftKeymasterContext(security_level) {} + +JavaCardSoftKeymasterContext::~JavaCardSoftKeymasterContext() {} + +keymaster_error_t JavaCardSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description, + const keymaster_key_origin_t origin, + const KeymasterKeyBlob& key_material, + KeymasterKeyBlob* blob, + AuthorizationSet* hw_enforced, + AuthorizationSet* sw_enforced) const { + if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) { + return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE; + } + + keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_, + os_patchlevel_, hw_enforced, sw_enforced); + if (error != KM_ERROR_OK) return error; + + AuthorizationSet hidden; + error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust); + if (error != KM_ERROR_OK) return error; + + size_t size = key_material.SerializedSize(); + + if (!blob->Reset(size)) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + + uint8_t* p = blob->writable_data(); + p = key_material.Serialize(p, blob->end()); + + return KM_ERROR_OK; +} + +inline keymaster_tag_t legacy_enum_conversion(const Tag value) { + return keymaster_tag_t(value); +} + +inline Tag legacy_enum_conversion(const keymaster_tag_t value) { + return Tag(value); +} + +inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { + keymaster_key_param_set_t set; + + set.params = new keymaster_key_param_t[keyParams.size()]; + set.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: + set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + set.params[i] = keymaster_param_bool(tag); + else + set.params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + set.params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: + set.params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + + return set; +} + +class KmParamSet : public keymaster_key_param_set_t { + public: + explicit KmParamSet(const hidl_vec& keyParams) + : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} + 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; } +}; + +EVP_PKEY* RSA_fromMaterial(const uint8_t* modulus, size_t mod_size) { + BIGNUM *n = BN_bin2bn(modulus, mod_size, NULL); + BIGNUM *e = BN_new();//bignum_decode(exp, 5); + char exp[] = "65537"; + BN_dec2bn(&e, exp); + + if (!n || !e) + return NULL; + + if (e && n) { + EVP_PKEY* pRsaKey = EVP_PKEY_new(); + RSA* rsa = RSA_new(); + rsa->e = e; + rsa->n = n; + EVP_PKEY_assign_RSA(pRsaKey, rsa); + return pRsaKey; + } else { + if (n) BN_free(n); + if (e) BN_free(e); + return NULL; + } +} + +EC_GROUP* ChooseGroup(keymaster_ec_curve_t ec_curve) { + switch (ec_curve) { + case KM_EC_CURVE_P_224: + return EC_GROUP_new_by_curve_name(NID_secp224r1); + break; + case KM_EC_CURVE_P_256: + return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + break; + case KM_EC_CURVE_P_384: + return EC_GROUP_new_by_curve_name(NID_secp384r1); + break; + case KM_EC_CURVE_P_521: + return EC_GROUP_new_by_curve_name(NID_secp521r1); + break; + default: + return nullptr; + break; + } +} + +EVP_PKEY* EC_fromMaterial(const uint8_t* pub_key, size_t key_size, keymaster_ec_curve_t ec_curve) { + + EC_GROUP *ec_group = ChooseGroup(ec_curve); + EC_POINT *p = EC_POINT_new(ec_group); + EC_KEY *ec_key = EC_KEY_new(); + EVP_PKEY *pEcKey = EVP_PKEY_new(); + + if((EC_KEY_set_group(ec_key, ec_group) != 1) || (EC_POINT_oct2point(ec_group, p, pub_key, key_size, NULL) != 1) + || (EC_KEY_set_public_key(ec_key, p) != 1) || (EVP_PKEY_set1_EC_KEY(pEcKey, ec_key) != 1)) { + return NULL; + } + + return pEcKey; +} + +keymaster_error_t JavaCardSoftKeymasterContext::LoadKey(const keymaster_algorithm_t algorithm, KeymasterKeyBlob&& key_material, + AuthorizationSet&& hw_enforced, + AuthorizationSet&& sw_enforced, + UniquePtr* key) const { + auto factory = (AsymmetricKeyFactory*)GetKeyFactory(algorithm); + UniquePtr asym_key; + keymaster_error_t error = KM_ERROR_OK; + const uint8_t* tmp = key_material.key_material; + const size_t temp_size = key_material.key_material_size; + EVP_PKEY* pkey = NULL; + + if(algorithm == KM_ALGORITHM_RSA) { + pkey = RSA_fromMaterial(tmp, temp_size); + } else if(algorithm == KM_ALGORITHM_EC) { + keymaster_ec_curve_t ec_curve = KM_EC_CURVE_P_256; + if (!hw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve) && + !sw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve)) { + return KM_ERROR_INVALID_ARGUMENT; + }//TODO also get ec_curve based on key size + pkey = EC_fromMaterial(tmp, temp_size, ec_curve); + } + if (!pkey) + return TranslateLastOpenSslError(); + UniquePtr pkey_deleter(pkey); + + error = factory->CreateEmptyKey(move(hw_enforced), move(sw_enforced), &asym_key); + if (error != KM_ERROR_OK) + return error; + + asym_key->key_material() = move(key_material); + if (!asym_key->EvpToInternal(pkey)) + error = TranslateLastOpenSslError(); + else + key->reset(asym_key.release()); + + return error; +} + +keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blob, + const AuthorizationSet& /*additional_params*/, + UniquePtr* key) const { + + // The JavaCardSoftKeymasterContext handle a key blob generated by JavaCard keymaster for public key operations. + // + // 1. A JavaCard keymaster key blob is a CborEncoded data of Secret, Nonce, AuthTag, KeyCharectristics and Public key. + // Here in public key operation we need only KeyCharectristics and Public key. + // Once these values extracted Public key is created based on parameters and returned. + // + + AuthorizationSet hw_enforced; + AuthorizationSet sw_enforced; + KeymasterKeyBlob key_material; + keymaster_error_t error; + + auto constructKey = [&, this] () mutable -> keymaster_error_t { + keymaster_algorithm_t algorithm; + if (!hw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm) && + !sw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm)) { + return KM_ERROR_INVALID_ARGUMENT; + } + + if (algorithm != KM_ALGORITHM_RSA && algorithm != KM_ALGORITHM_EC) { + return KM_ERROR_INCOMPATIBLE_ALGORITHM; + } + error = LoadKey(algorithm, move(key_material), move(hw_enforced), + move(sw_enforced), key); + return error; + }; + + CborConverter cc; + std::unique_ptr item; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + std::vector cborKey(blob.key_material_size); +// std::vector cborKey(187); + + for(size_t i = 0; i < blob.key_material_size; i++) { + cborKey[i] = blob.key_material[i]; + } +/*uint8_t tempBlob[] = {0x85, 0x58, 0x20, 0xDA, 0x29, 0xC7, 0x1A, 0x8C, 0xE7, 0x6A, 0x0D, 0xFD, +0x2E, 0x53, 0x06, 0x81, 0x85, 0x37, 0x2D, 0x9E, 0x74, 0xE7, 0xF1, 0xD5, +0x3F, 0x0E, 0xAB, 0x1A, 0xF8, 0xE9, 0x46, 0xFD, 0xDC, 0x37, 0x54, 0x4C, +0xE9, 0xA7, 0xD0, 0x71, 0x96, 0xCC, 0x66, 0x18, 0xF0, 0x53, 0xD1, 0x30, +0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x82, 0xA1, 0x1A, 0x30, 0x00, 0x01, 0xF5, 0x1A, 0x01, 0x02, 0x03, +0x04, 0xA6, 0x1A, 0x10, 0x00, 0x00, 0x02, 0x03, 0x1A, 0x50, 0x00, 0x00, +0xC8, 0x1A, 0x00, 0x01, 0x00, 0x01, 0x1A, 0x30, 0x00, 0x00, 0x03, 0x19, +0x01, 0x00, 0x1A, 0x10, 0x00, 0x02, 0xBE, 0x00, 0x1A, 0x30, 0x00, 0x02, +0xC1, 0x00, 0x1A, 0x30, 0x00, 0x02, 0xC2, 0x1A, 0x00, 0x03, 0x15, 0x14, +0x58, 0x41, 0x04, 0x2B, 0xF1, 0x84, 0xD4, 0xFB, 0x63, 0x44, 0x20, 0xD0, +0xA3, 0x7D, 0x6A, 0xC1, 0xC5, 0x26, 0x12, 0xCD, 0x79, 0x77, 0x81, 0x22, +0x33, 0x30, 0x70, 0xF7, 0x25, 0x6D, 0x75, 0xE0, 0xD4, 0xD0, 0x50, 0xD6, +0x80, 0x65, 0x2A, 0x44, 0x0B, 0x8E, 0xFC, 0xA0, 0x8B, 0xC5, 0xF4, 0x8A, +0xCA, 0x4B, 0x89, 0x6E, 0x8B, 0xFC, 0x38, 0xB7, 0xC9, 0xB9, 0xB6, 0xE7, +0x57, 0xE6, 0x53, 0xE9, 0xBF, 0x94, 0x3A}; + for(size_t i = 0; i < 187; i++) { + cborKey[i] = tempBlob[i]; + } +*/ + std::tie(item, errorCode) = cc.decodeData(cborKey, false); + if (item != nullptr) { + std::vector temp; + cc.getBinaryArray(item, 4, temp); + + key_material = {temp.data(), temp.size()}; + temp.clear(); + KeyCharacteristics keyCharacteristics; + cc.getKeyCharacteristics(item, 3, keyCharacteristics); + + sw_enforced.Reinitialize(KmParamSet(keyCharacteristics.softwareEnforced)); + hw_enforced.Reinitialize(KmParamSet(keyCharacteristics.hardwareEnforced)); + } + return constructKey(); +} +} // namespace keymaster diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index b3a21fa0..33136850 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -18,6 +18,7 @@ cc_library { srcs: [ "4.1/JavacardKeymaster4Device.cpp", "4.1/CborConverter.cpp", + "4.1/java_card_soft_keymaster_context.cpp", "4.1/JavacardOperationContext.cpp", ], local_include_dirs: [ diff --git a/HAL/keymaster/include/java_card_soft_keymaster_context.h b/HAL/keymaster/include/java_card_soft_keymaster_context.h new file mode 100644 index 00000000..07be5c9e --- /dev/null +++ b/HAL/keymaster/include/java_card_soft_keymaster_context.h @@ -0,0 +1,68 @@ +/* + * Copyright 2015 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 SYSTEM_KEYMASTER_JAVA_CARD_SOFT_KEYMASTER_CONTEXT_H_ +#define SYSTEM_KEYMASTER_JAVA_CARD_SOFT_KEYMASTER_CONTEXT_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace keymaster { + +class SoftKeymasterKeyRegistrations; +class Keymaster0Engine; +class Keymaster1Engine; +class Key; + +/** + * SoftKeymasterContext provides the context for a non-secure implementation of AndroidKeymaster. + */ +class JavaCardSoftKeymasterContext : public keymaster::PureSoftKeymasterContext { + keymaster_error_t LoadKey(const keymaster_algorithm_t algorithm, KeymasterKeyBlob&& key_material, + AuthorizationSet&& hw_enforced, + AuthorizationSet&& sw_enforced, + UniquePtr* key) const; + public: + // Security level must only be used for testing. + explicit JavaCardSoftKeymasterContext( + keymaster_security_level_t security_level = KM_SECURITY_LEVEL_SOFTWARE); + ~JavaCardSoftKeymasterContext() override; + + keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob, + const AuthorizationSet& additional_params, + UniquePtr* key) const override; + /********************************************************************************************* + * Implement SoftwareKeyBlobMaker + */ + keymaster_error_t CreateKeyBlob(const AuthorizationSet& auths, keymaster_key_origin_t origin, + const KeymasterKeyBlob& key_material, KeymasterKeyBlob* blob, + AuthorizationSet* hw_enforced, + AuthorizationSet* sw_enforced) const override; + +}; + +} // namespace keymaster + +#endif // SYSTEM_KEYMASTER_PURE_SOFT_KEYMASTER_CONTEXT_H_ From 76d43caf42ca3526e801dafd0280855633a3bd39 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 15 Jun 2020 04:51:05 +0530 Subject: [PATCH 44/58] Added validations in OperationContext --- .../4.1/JavacardOperationContext.cpp | 86 +++++++++++++++---- .../include/JavacardOperationContext.h | 50 +++++++++-- 2 files changed, 113 insertions(+), 23 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index 096ace36..185960d0 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -18,8 +18,10 @@ #include #define MAX_ALLOWED_INPUT_SIZE 512 -#define AES_BLOCK_SIZE 16 -#define DES_BLOCK_SIZE 8 +#define AES_BLOCK_SIZE 16 +#define DES_BLOCK_SIZE 8 +#define RSA_INPUT_MSG_LEN 245 /*(256-11)*/ +#define EC_INPUT_MSG_LEN 32 namespace keymaster { namespace V4_1 { @@ -30,25 +32,15 @@ enum class Operation { Finish = 1 }; -struct BufferedData { - uint8_t buf[MAX_BUF_SIZE]; - int buf_len; -}; - -struct OperationData { - OperationInfo info; - BufferedData data; -}; - -ErrorCode OperationContext::setOperationData(uint64_t operationHandle, OperationInfo& operInfo) { +ErrorCode OperationContext::setOperationInfo(uint64_t operationHandle, OperationInfo& operInfo) { OperationData data; data.info = operInfo; operationTable[operationHandle] = data; return ErrorCode::OK; } -ErrorCode OperationContext::getOperationData(uint64_t operHandle, OperationInfo& operInfo) { +ErrorCode OperationContext::getOperationInfo(uint64_t operHandle, OperationInfo& operInfo) { auto itr = operationTable.find(operHandle); if(itr != operationTable.end()) { operInfo = itr->second.info; @@ -65,8 +57,50 @@ ErrorCode OperationContext::clearOperationData(uint64_t operHandle) { return ErrorCode::OK; } -ErrorCode OperationContext::update(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb) { +ErrorCode OperationContext::validateInputData(uint64_t operHandle, Operation opr, std::vector& actualInput, std::vector& input) { + ErrorCode errorCode = ErrorCode::OK; + OperationData oprData; + + if(ErrorCode::OK != (errorCode = getOperationData(operHandle, oprData))) { + return errorCode; + } + + if(Algorithm::RSA == oprData.info.alg && Digest::NONE == oprData.info.digest) { + if(actualInput.size() > RSA_INPUT_MSG_LEN) + return ErrorCode::INVALID_INPUT_LENGTH; + } else if(Algorithm::EC == oprData.info.alg && Digest::NONE == oprData.info.digest) { + if(actualInput.size() > EC_INPUT_MSG_LEN) { + /* Silently truncate the input */ + for(int i=0; i < EC_INPUT_MSG_LEN; i++) { + input.push_back(actualInput[i]); + } + return errorCode; + } + } + + if(opr == Operation::Finish) { + if(oprData.info.pad == PaddingMode::NONE && oprData.info.alg == Algorithm::AES) { + if(((oprData.data.buf_len+actualInput.size()) % AES_BLOCK_SIZE) != 0) + return ErrorCode::INVALID_INPUT_LENGTH; + } + if(oprData.info.pad == PaddingMode::NONE && oprData.info.alg == Algorithm::TRIPLE_DES) { + if(((oprData.data.buf_len+actualInput.size()) % DES_BLOCK_SIZE) != 0) + return ErrorCode::INVALID_INPUT_LENGTH; + } + } + input = actualInput; + return errorCode; +} + +ErrorCode OperationContext::update(uint64_t operHandle, std::vector& actualInput, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; + std::vector input; + + /* Validate the input data */ + if(ErrorCode::OK != (errorCode = validateInputData(operHandle, Operation::Update, actualInput, input))) { + return errorCode; + } + if (input.size() > MAX_ALLOWED_INPUT_SIZE) { int noOfChunks = input.size()/MAX_ALLOWED_INPUT_SIZE; int extraData = input.size()%MAX_ALLOWED_INPUT_SIZE; @@ -95,8 +129,16 @@ ErrorCode OperationContext::update(uint64_t operHandle, std::vector& in return errorCode; } -ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb) { +ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& actualInput, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; + std::vector input; + OperationData oprData; + + /* Validate the input data */ + if(ErrorCode::OK != (errorCode = validateInputData(operHandle, Operation::Update, actualInput, input))) { + return errorCode; + } + if (input.size() > MAX_ALLOWED_INPUT_SIZE) { int noOfChunks = input.size()/MAX_ALLOWED_INPUT_SIZE; int extraData = input.size()%MAX_ALLOWED_INPUT_SIZE; @@ -122,6 +164,18 @@ ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& in return errorCode; } } + + if(ErrorCode::OK != (errorCode = getOperationData(operHandle, oprData))) { + return errorCode; + } + + /* Send if any buffered data is remaining */ + if(oprData.data.buf_len > 0) { + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, nullptr, 0, + Operation::Finish, cb))) { + return errorCode; + } + } return errorCode; } diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h index e63b5011..a1763650 100644 --- a/HAL/keymaster/include/JavacardOperationContext.h +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -30,15 +30,28 @@ namespace javacard { using ::android::hardware::keymaster::V4_0::ErrorCode; using ::android::hardware::keymaster::V4_0::Algorithm; using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::Digest; +using ::android::hardware::keymaster::V4_0::PaddingMode; using sendDataToSE_cb = std::function& data)>; enum class Operation; -struct OperationData; + +struct BufferedData { + uint8_t buf[MAX_BUF_SIZE]; + int buf_len; +}; struct OperationInfo { Algorithm alg; KeyPurpose purpose; + Digest digest; + PaddingMode pad; +}; + +struct OperationData { + OperationInfo info; + BufferedData data; }; class OperationContext { @@ -46,31 +59,54 @@ class OperationContext { public: OperationContext(){} ~OperationContext() {} - ErrorCode setOperationData(uint64_t operationHandle, OperationInfo& oeprInfo); - ErrorCode getOperationData(uint64_t operHandle, OperationInfo& operInfo); + ErrorCode setOperationInfo(uint64_t operationHandle, OperationInfo& oeprInfo); + ErrorCode getOperationInfo(uint64_t operHandle, OperationInfo& operInfo); ErrorCode clearOperationData(uint64_t operationHandle); ErrorCode update(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); ErrorCode finish(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); private: std::map operationTable; + + inline ErrorCode getOperationData(uint64_t operHandle, OperationData& oprData) { + auto itr = operationTable.find(operHandle); + if(itr != operationTable.end()) { + oprData = itr->second; + return ErrorCode::OK; + } + return ErrorCode::INVALID_OPERATION_HANDLE; + } + + ErrorCode validateInputData(uint64_t operHandle, Operation opr, std::vector& actualInput, + std::vector& input); ErrorCode internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& out); inline ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; std::vector out; - if(ErrorCode::OK != (errorCode = internalUpdate(operHandle, data, len, - opr, out))) { + OperationData oprData; + + if(ErrorCode::OK != (errorCode = getOperationData(operHandle, oprData))) { return errorCode; } + + if(Algorithm::AES == oprData.info.alg || Algorithm::TRIPLE_DES == oprData.info.alg) { + if(ErrorCode::OK != (errorCode = internalUpdate(operHandle, data, len, + opr, out))) { + return errorCode; + } + } else { + /* Other algorithms no buffering required */ + for(int i = 0; i < len; i++) { + out.push_back(data[i]); + } + } if(ErrorCode::OK != (errorCode = cb(out))) { return errorCode; } return errorCode; } - - }; } // namespace javacard From 5402afb5f4f246addd4dd98f04541d077a29b487 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 15 Jun 2020 22:22:41 +0530 Subject: [PATCH 45/58] Integration of OperationContext with JavacardKeymaster4Device class --- .../4.1/JavacardKeymaster4Device.cpp | 138 ++++++++++++------ .../4.1/JavacardOperationContext.cpp | 45 ++++-- .../include/JavacardKeymaster4Device.h | 2 + .../include/JavacardOperationContext.h | 18 ++- 4 files changed, 141 insertions(+), 62 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 11bcd8b9..c9ebb70f 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -206,7 +206,7 @@ JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::A context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); return context; }(), - kOperationTableSize)), setUpBootParams(false) { + kOperationTableSize)), oprCtx_(new OperationContext()), setUpBootParams(false) { pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( android::base::GetBoolProperty("ro.kernel.qemu", false))); pTransportFactory->openConnection(); @@ -773,7 +773,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -782,6 +782,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< if (item != nullptr) { cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getUint64(item, 2, operationHandle); + /* Store the operationInfo */ + oprCtx_->setOperationInfo(operationHandle, purpose, inParams); } } _hidl_cb(errorCode, outParams, operationHandle); @@ -807,29 +809,44 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi outParams = kmParamSet2Hidl(response.output_params); output = kmBuffer2hidlVec(response.output); } else if(response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; - - // Convert input data to cbor format - array.add(operationHandle); - cborConverter_.addKeyparameters(array, inParams); - array.add(std::vector(input)); - cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); - std::vector cborData = array.encode(); - - errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getUint64(item, 1, inputConsumed); - cborConverter_.getKeyParameters(item, 2, outParams); - cborConverter_.getBinaryArray(item, 3, output); + std::vector tempOut; + /* OperationContext calls this below sendDataCallback callback function. This callback + * may be called multiple times if the input data is larger than MAX_ALLOWED_INPUT_SIZE. + */ + auto sendDataCallback = [&](std::vector& data, bool) -> ErrorCode { + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; + + // Convert input data to cbor format + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(data); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + /*Ignore inputConsumed from javacard SE since HAL consumes all the input */ + //cborConverter_.getUint64(item, 1, inputConsumed); + if(outParams.size() == 0) + cborConverter_.getKeyParameters(item, 2, outParams); + cborConverter_.getBinaryArray(item, 3, tempOut); + } } + return errorCode; + }; + if(ErrorCode::OK == (errorCode = oprCtx_->update(operationHandle, std::vector(input), + sendDataCallback))) { + /* Consumed all the input */ + inputConsumed = input.size(); + output = tempOut; } } _hidl_cb(errorCode, inputConsumed, outParams, output); @@ -854,29 +871,56 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi outParams = kmParamSet2Hidl(response.output_params); output = kmBuffer2hidlVec(response.output); } else if (response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; - - // Convert input data to cbor format - array.add(operationHandle); - cborConverter_.addKeyparameters(array, inParams); - array.add(std::vector(input)); - array.add(std::vector(signature)); - cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); - std::vector cborData = array.encode(); - - errorCode = sendData(this, pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getKeyParameters(item, 1, outParams); - cborConverter_.getBinaryArray(item, 2, output); + std::vector tempOut; + /* OperationContext calls this below sendDataCallback callback function. This callback + * may be called multiple times if the input data is larger than MAX_ALLOWED_INPUT_SIZE. + * This callback function decides whether to call update/finish instruction based on the + * input received from the OperationContext through finish variable. + * if finish variable is false update instruction is called, if it is true finish instruction + * is called. + */ + auto sendDataCallback = [&](std::vector& data, bool finish) -> ErrorCode { + cppbor::Array array; + Instruction ins; + std::unique_ptr item; + std::vector cborOutData; + int keyParamPos, outputPos; + + // Convert input data to cbor format + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(data); + if(finish) { + array.add(std::vector(signature)); + ins = Instruction::INS_FINISH_OPERATION_CMD; + keyParamPos = 1; + outputPos = 2; + } else { + ins = Instruction::INS_UPDATE_OPERATION_CMD; + keyParamPos = 2; + outputPos = 3; } + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + errorCode = sendData(this, pTransportFactory, ins, cborData, cborOutData); + + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + if(outParams.size() == 0) + cborConverter_.getKeyParameters(item, keyParamPos, outParams); + cborConverter_.getBinaryArray(item, outputPos, tempOut); + } + } + return errorCode; + }; + if(ErrorCode::OK == (errorCode = oprCtx_->finish(operationHandle, std::vector(input), + sendDataCallback))) { + output = tempOut; } } _hidl_cb(errorCode, outParams, output); @@ -900,6 +944,8 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); } + /* Delete the entry on this operationHandle */ + oprCtx_->clearOperationData(operationHandle); return errorCode; } diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index 185960d0..57d5af5e 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -32,6 +32,35 @@ enum class Operation { Finish = 1 }; +inline ErrorCode hidlParamSet2OperatinInfo(const hidl_vec& params, OperationInfo& info) { + for(int i = 0; i < params.size(); i++) { + const KeyParameter ¶m = params[i]; + switch(param.tag) { + case Tag::ALGORITHM: + info.alg = static_cast(param.f.integer); + break; + case Tag::DIGEST: + info.digest = static_cast(param.f.integer); + break; + case Tag::PADDING: + info.pad = static_cast(param.f.integer); + break; + default: + continue; + } + } + return ErrorCode::OK; +} + +ErrorCode OperationContext::setOperationInfo(uint64_t operationHandle, KeyPurpose purpose, const hidl_vec& params) { + ErrorCode errorCode = ErrorCode::OK; + OperationInfo info; + if(ErrorCode::OK != (errorCode = hidlParamSet2OperatinInfo(params, info))) { + return errorCode; + } + info.purpose = purpose; + return setOperationInfo(operationHandle, info); +} ErrorCode OperationContext::setOperationInfo(uint64_t operationHandle, OperationInfo& operInfo) { OperationData data; @@ -57,7 +86,7 @@ ErrorCode OperationContext::clearOperationData(uint64_t operHandle) { return ErrorCode::OK; } -ErrorCode OperationContext::validateInputData(uint64_t operHandle, Operation opr, std::vector& actualInput, std::vector& input) { +ErrorCode OperationContext::validateInputData(uint64_t operHandle, Operation opr, const std::vector& actualInput, std::vector& input) { ErrorCode errorCode = ErrorCode::OK; OperationData oprData; @@ -92,7 +121,7 @@ ErrorCode OperationContext::validateInputData(uint64_t operHandle, Operation opr return errorCode; } -ErrorCode OperationContext::update(uint64_t operHandle, std::vector& actualInput, sendDataToSE_cb cb) { +ErrorCode OperationContext::update(uint64_t operHandle, const std::vector& actualInput, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; std::vector input; @@ -129,7 +158,7 @@ ErrorCode OperationContext::update(uint64_t operHandle, std::vector& ac return errorCode; } -ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& actualInput, sendDataToSE_cb cb) { +ErrorCode OperationContext::finish(uint64_t operHandle, const std::vector& actualInput, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; std::vector input; OperationData oprData; @@ -169,12 +198,10 @@ ErrorCode OperationContext::finish(uint64_t operHandle, std::vector& ac return errorCode; } - /* Send if any buffered data is remaining */ - if(oprData.data.buf_len > 0) { - if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, nullptr, 0, - Operation::Finish, cb))) { - return errorCode; - } + /* Send if any buffered data is remaining or to call finish */ + if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, nullptr, 0, + Operation::Finish, cb, true))) { + return errorCode; } return errorCode; } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 6d0be552..95299956 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace keymaster { namespace V4_1 { @@ -94,6 +95,7 @@ class JavacardKeymaster4Device : public IKeymasterDevice { private: std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; + std::unique_ptr oprCtx_; bool setUpBootParams; }; diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h index a1763650..c784b1fe 100644 --- a/HAL/keymaster/include/JavacardOperationContext.h +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -27,13 +27,16 @@ namespace keymaster { namespace V4_1 { namespace javacard { +using ::android::hardware::hidl_vec; using ::android::hardware::keymaster::V4_0::ErrorCode; using ::android::hardware::keymaster::V4_0::Algorithm; using ::android::hardware::keymaster::V4_0::KeyPurpose; using ::android::hardware::keymaster::V4_0::Digest; using ::android::hardware::keymaster::V4_0::PaddingMode; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::Tag; -using sendDataToSE_cb = std::function& data)>; +using sendDataToSE_cb = std::function& data, bool finish)>; enum class Operation; @@ -60,10 +63,11 @@ class OperationContext { OperationContext(){} ~OperationContext() {} ErrorCode setOperationInfo(uint64_t operationHandle, OperationInfo& oeprInfo); + ErrorCode setOperationInfo(uint64_t operationHandle, KeyPurpose purpose, const hidl_vec& params); ErrorCode getOperationInfo(uint64_t operHandle, OperationInfo& operInfo); ErrorCode clearOperationData(uint64_t operationHandle); - ErrorCode update(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); - ErrorCode finish(uint64_t operHandle, std::vector& input, sendDataToSE_cb cb); + ErrorCode update(uint64_t operHandle, const std::vector& input, sendDataToSE_cb cb); + ErrorCode finish(uint64_t operHandle, const std::vector& input, sendDataToSE_cb cb); private: std::map operationTable; @@ -77,12 +81,12 @@ class OperationContext { return ErrorCode::INVALID_OPERATION_HANDLE; } - ErrorCode validateInputData(uint64_t operHandle, Operation opr, std::vector& actualInput, + ErrorCode validateInputData(uint64_t operHandle, Operation opr, const std::vector& actualInput, std::vector& input); ErrorCode internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& out); inline ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, - sendDataToSE_cb cb) { + sendDataToSE_cb cb, bool finish=false) { ErrorCode errorCode = ErrorCode::OK; std::vector out; OperationData oprData; @@ -98,11 +102,11 @@ class OperationContext { } } else { /* Other algorithms no buffering required */ - for(int i = 0; i < len; i++) { + for(size_t i = 0; i < len; i++) { out.push_back(data[i]); } } - if(ErrorCode::OK != (errorCode = cb(out))) { + if(ErrorCode::OK != (errorCode = cb(out, finish))) { return errorCode; } return errorCode; From e9921a8e05131900ec192336cab0257b73123eda Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 15 Jun 2020 23:14:27 +0530 Subject: [PATCH 46/58] decode parse wrapped keyblob in importWrappedKey --- .../4.1/JavacardKeymaster4Device.cpp | 109 +++++++++++++----- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index c9ebb70f..cf16894b 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -200,6 +202,42 @@ inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { return result; } +static inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { + for(int i = 0; i < size; ++i) { + to.push_back(from[i]); + } +} + +static inline ErrorCode parseWrappedKey(const hidl_vec& wrappedKeyData, std::vector& iv, std::vector& transitKey, +std::vector& secureKey, std::vector& tag, hidl_vec& authList, KeyFormat& +keyFormat, std::vector& wrappedKeyDescription) { + KeymasterBlob kmIv; + KeymasterKeyBlob kmTransitKey; + KeymasterKeyBlob kmSecureKey; + KeymasterBlob kmTag; + AuthorizationSet authSet; + keymaster_key_format_t kmKeyFormat; + KeymasterBlob kmWrappedKeyDescription; + KeymasterKeyBlob kmWrappedKeyData; + + kmWrappedKeyData.key_material = dup_buffer(wrappedKeyData.data(), wrappedKeyData.size()); + + keymaster_error_t error = parse_wrapped_key(kmWrappedKeyData, &kmIv, &kmTransitKey, + &kmSecureKey, &kmTag, &authSet, + &kmKeyFormat, &kmWrappedKeyDescription); + if (error != KM_ERROR_OK) return legacy_enum_conversion(error); + blob2Vec(kmIv.data, kmIv.data_length, iv); + blob2Vec(kmTransitKey.key_material, kmTransitKey.key_material_size, transitKey); + blob2Vec(kmSecureKey.key_material, kmSecureKey.key_material_size, secureKey); + blob2Vec(kmTag.data, kmTag.data_length, tag); + authList = kmParamSet2Hidl(authSet); + keyFormat = static_cast(kmKeyFormat); + blob2Vec(kmWrappedKeyDescription.data, kmWrappedKeyDescription.data_length, wrappedKeyDescription); + + return ErrorCode::OK; +} + + JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( []() -> auto { auto context = new JavaCardSoftKeymasterContext(); @@ -508,31 +546,31 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k return Void(); } - cppbor::Array array; - std::unique_ptr item; - hidl_vec keyBlob; - std::vector cborOutData; - ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - KeyCharacteristics keyCharacteristics; - - cborConverter_.addKeyparameters(array, keyParams); - array.add(static_cast(KeyFormat::RAW)); //PKCS8 is already converted to RAW - array.add(std::vector(inKey)); - std::vector cborData = array.encode(); - - errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getBinaryArray(item, 1, keyBlob); - cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); - } - } - _hidl_cb(errorCode, keyBlob, keyCharacteristics); - return Void(); + cppbor::Array array; + std::unique_ptr item; + hidl_vec keyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; + + cborConverter_.addKeyparameters(array, keyParams); + array.add(static_cast(KeyFormat::RAW)); //PKCS8 is already converted to RAW + array.add(std::vector(inKey)); + std::vector cborData = array.encode(); + + errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + if (item != nullptr) { + cborConverter_.getBinaryArray(item, 1, keyBlob); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); } Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { @@ -542,8 +580,25 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; - - array.add(std::vector(wrappedKeyData)); + std::vector iv; + std::vector transitKey; + std::vector secureKey; + std::vector tag; + hidl_vec authList; + KeyFormat keyFormat; + std::vector wrappedKeyDescription; + + if(ErrorCode::OK != (errorCode = parseWrappedKey(wrappedKeyData, iv, transitKey, secureKey, + tag, authList, keyFormat, wrappedKeyDescription))) { + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); + } + array.add(transitKey); + array.add(iv); + array.add(static_cast(keyFormat)); + cborConverter_.addKeyparameters(array, authList); + array.add(secureKey); + array.add(tag); array.add(std::vector(wrappingKeyBlob)); array.add(std::vector(maskingKey)); cborConverter_.addKeyparameters(array, unwrappingParams); From ba78d68f383e8eda598bd8a0ad0ca883b27afaa6 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 17 Jun 2020 20:53:43 +0530 Subject: [PATCH 47/58] 1. validations for sign and encrypt for Digest::None case 2. Fix the issue in cbor for HardwareAuthToken and VerificationToken. --- HAL/keymaster/4.1/CborConverter.cpp | 26 +++++----- .../4.1/JavacardKeymaster4Device.cpp | 6 +++ .../4.1/JavacardOperationContext.cpp | 34 ++++++++----- .../include/JavacardOperationContext.h | 49 ++++++++++++++++--- 4 files changed, 83 insertions(+), 32 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index b54b9337..c0643ed8 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -297,22 +297,26 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, bool CborConverter::addVerificationToken(Array& array, const VerificationToken& verificationToken) { - array.add(verificationToken.challenge); - array.add(verificationToken.timestamp); - addKeyparameters(array, verificationToken.parametersVerified); - array.add(static_cast(verificationToken.securityLevel)); - array.add((std::vector(verificationToken.mac))); + Array vToken; + vToken.add(verificationToken.challenge); + vToken.add(verificationToken.timestamp); + addKeyparameters(vToken, verificationToken.parametersVerified); + vToken.add(static_cast(verificationToken.securityLevel)); + vToken.add((std::vector(verificationToken.mac))); + array.add(std::move(vToken)); return true; } bool CborConverter::addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken) { - array.add(authToken.challenge); - array.add(authToken.userId); - array.add(authToken.authenticatorId); - array.add(static_cast(authToken.authenticatorType)); - array.add(authToken.timestamp); - array.add((std::vector(authToken.mac))); + Array hwAuthToken; + hwAuthToken.add(authToken.challenge); + hwAuthToken.add(authToken.userId); + hwAuthToken.add(authToken.authenticatorId); + hwAuthToken.add(static_cast(authToken.authenticatorType)); + hwAuthToken.add(authToken.timestamp); + hwAuthToken.add((std::vector(authToken.mac))); + array.add(std::move(hwAuthToken)); return true; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index cf16894b..ef1e4f04 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -904,6 +904,10 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi output = tempOut; } } + if(ErrorCode::OK != errorCode) { + /* Delete the entry on this operationHandle */ + oprCtx_->clearOperationData(operationHandle); + } _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); } @@ -978,6 +982,8 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi output = tempOut; } } + /* Delete the entry on this operationHandle */ + oprCtx_->clearOperationData(operationHandle); _hidl_cb(errorCode, outParams, output); return Void(); } diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index 57d5af5e..0e1de44c 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -22,6 +22,8 @@ #define DES_BLOCK_SIZE 8 #define RSA_INPUT_MSG_LEN 245 /*(256-11)*/ #define EC_INPUT_MSG_LEN 32 +#define MAX_RSA_BUFFER_SIZE 256 +#define MAX_EC_BUFFER_SIZE 32 namespace keymaster { namespace V4_1 { @@ -94,20 +96,31 @@ ErrorCode OperationContext::validateInputData(uint64_t operHandle, Operation opr return errorCode; } - if(Algorithm::RSA == oprData.info.alg && Digest::NONE == oprData.info.digest) { - if(actualInput.size() > RSA_INPUT_MSG_LEN) - return ErrorCode::INVALID_INPUT_LENGTH; - } else if(Algorithm::EC == oprData.info.alg && Digest::NONE == oprData.info.digest) { - if(actualInput.size() > EC_INPUT_MSG_LEN) { + if(KeyPurpose::SIGN == oprData.info.purpose) { + if(Algorithm::RSA == oprData.info.alg && Digest::NONE == oprData.info.digest) { + if((oprData.data.buf_len+actualInput.size()) > RSA_INPUT_MSG_LEN) + return ErrorCode::INVALID_INPUT_LENGTH; + } else if(Algorithm::EC == oprData.info.alg && Digest::NONE == oprData.info.digest) { /* Silently truncate the input */ - for(int i=0; i < EC_INPUT_MSG_LEN; i++) { - input.push_back(actualInput[i]); + if(oprData.data.buf_len >= EC_INPUT_MSG_LEN) { + return ErrorCode::OK; + } else if(actualInput.size()+oprData.data.buf_len > EC_INPUT_MSG_LEN) { + for(int i=oprData.data.buf_len,j=0; i < EC_INPUT_MSG_LEN; ++i,++j) { + input.push_back(actualInput[j]); + } + return ErrorCode::OK; } - return errorCode; + } + } + + if(KeyPurpose::DECRYPT == oprData.info.purpose && Algorithm::RSA == oprData.info.alg) { + if((oprData.data.buf_len+actualInput.size()) > MAX_RSA_BUFFER_SIZE) { + return ErrorCode::INVALID_INPUT_LENGTH; } } if(opr == Operation::Finish) { + if(oprData.info.pad == PaddingMode::NONE && oprData.info.alg == Algorithm::AES) { if(((oprData.data.buf_len+actualInput.size()) % AES_BLOCK_SIZE) != 0) return ErrorCode::INVALID_INPUT_LENGTH; @@ -161,7 +174,6 @@ ErrorCode OperationContext::update(uint64_t operHandle, const std::vector& actualInput, sendDataToSE_cb cb) { ErrorCode errorCode = ErrorCode::OK; std::vector input; - OperationData oprData; /* Validate the input data */ if(ErrorCode::OK != (errorCode = validateInputData(operHandle, Operation::Update, actualInput, input))) { @@ -194,10 +206,6 @@ ErrorCode OperationContext::finish(uint64_t operHandle, const std::vector #include -#define MAX_BUF_SIZE 32 +#define MAX_BUF_SIZE 256 namespace keymaster { namespace V4_1 { @@ -85,7 +85,7 @@ class OperationContext { std::vector& input); ErrorCode internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& out); - inline ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, + ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, sendDataToSE_cb cb, bool finish=false) { ErrorCode errorCode = ErrorCode::OK; std::vector out; @@ -100,15 +100,48 @@ class OperationContext { opr, out))) { return errorCode; } + + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } } else { - /* Other algorithms no buffering required */ - for(size_t i = 0; i < len; i++) { - out.push_back(data[i]); + if(oprData.info.digest == Digest::NONE) { + if(finish) { + for(int i = 0; i < oprData.data.buf_len; ++i) { + out[i] = oprData.data.buf[i]; + } + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } + } else { + /* For RSA/EC algorithms just do buffering, don't send data to SE in update. + * input message length should not be more than the MAX_BUF_SIZE. + */ + if(oprData.data.buf_len <= MAX_BUF_SIZE) { + size_t bufIndex = oprData.data.buf_len; + size_t pos = 0; + for(; (pos < len) && (pos < (MAX_BUF_SIZE-bufIndex)); pos++) + { + oprData.data.buf[bufIndex+pos] = data[pos]; + } + oprData.data.buf_len += pos; + } + } + } else { + for(size_t j=0; j < len; ++j) + { + out[j] = data[j]; + } + /* if len=0, then no need to call the callback, since there is no information to be send to javacard, + * but if finish flag is true irrespective of len callback should be called. + */ + if(len != 0 || finish) { + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } + } } } - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; - } return errorCode; } }; From abe6e2712fb887b8a1a2cec07fea43c4b8c4377f Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 18 Jun 2020 16:29:49 +0530 Subject: [PATCH 48/58] Fixed the issues observed while running vts test case EncryptionOperationsTest#RsaNoPaddingShortMessage. --- HAL/keymaster/4.1/CborConverter.cpp | 5 +- .../4.1/JavacardOperationContext.cpp | 1 + .../include/JavacardOperationContext.h | 117 +++++++++--------- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index c0643ed8..e7217c2d 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -297,10 +297,13 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, bool CborConverter::addVerificationToken(Array& array, const VerificationToken& verificationToken) { + std::vector encodedParamsVerified; Array vToken; vToken.add(verificationToken.challenge); vToken.add(verificationToken.timestamp); - addKeyparameters(vToken, verificationToken.parametersVerified); + //addKeyparameters(vToken, verificationToken.parametersVerified); + /* TODO Need to get proper encodedParamsVerified */ + vToken.add(std::move(encodedParamsVerified)); vToken.add(static_cast(verificationToken.securityLevel)); vToken.add((std::vector(verificationToken.mac))); array.add(std::move(vToken)); diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index 0e1de44c..b37b4a18 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -67,6 +67,7 @@ ErrorCode OperationContext::setOperationInfo(uint64_t operationHandle, KeyPurpos ErrorCode OperationContext::setOperationInfo(uint64_t operationHandle, OperationInfo& operInfo) { OperationData data; data.info = operInfo; + memset((void*)&(data.data), 0x00, sizeof(data.data)); operationTable[operationHandle] = data; return ErrorCode::OK; } diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h index f5e78a9c..d78b1aea 100644 --- a/HAL/keymaster/include/JavacardOperationContext.h +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -42,7 +42,7 @@ enum class Operation; struct BufferedData { uint8_t buf[MAX_BUF_SIZE]; - int buf_len; + size_t buf_len; }; struct OperationInfo { @@ -86,64 +86,63 @@ class OperationContext { ErrorCode internalUpdate(uint64_t operHandle, uint8_t* input, size_t input_len, Operation opr, std::vector& out); ErrorCode handleInternalUpdate(uint64_t operHandle, uint8_t* data, size_t len, Operation opr, - sendDataToSE_cb cb, bool finish=false) { - ErrorCode errorCode = ErrorCode::OK; - std::vector out; - OperationData oprData; - - if(ErrorCode::OK != (errorCode = getOperationData(operHandle, oprData))) { - return errorCode; - } - - if(Algorithm::AES == oprData.info.alg || Algorithm::TRIPLE_DES == oprData.info.alg) { - if(ErrorCode::OK != (errorCode = internalUpdate(operHandle, data, len, - opr, out))) { - return errorCode; - } - - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; - } - } else { - if(oprData.info.digest == Digest::NONE) { - if(finish) { - for(int i = 0; i < oprData.data.buf_len; ++i) { - out[i] = oprData.data.buf[i]; - } - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; - } - } else { - /* For RSA/EC algorithms just do buffering, don't send data to SE in update. - * input message length should not be more than the MAX_BUF_SIZE. - */ - if(oprData.data.buf_len <= MAX_BUF_SIZE) { - size_t bufIndex = oprData.data.buf_len; - size_t pos = 0; - for(; (pos < len) && (pos < (MAX_BUF_SIZE-bufIndex)); pos++) - { - oprData.data.buf[bufIndex+pos] = data[pos]; - } - oprData.data.buf_len += pos; - } - } - } else { - for(size_t j=0; j < len; ++j) - { - out[j] = data[j]; - } - /* if len=0, then no need to call the callback, since there is no information to be send to javacard, - * but if finish flag is true irrespective of len callback should be called. - */ - if(len != 0 || finish) { - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; - } - } - } - } - return errorCode; - } + sendDataToSE_cb cb, bool finish=false) { + ErrorCode errorCode = ErrorCode::OK; + std::vector out; + + if(Algorithm::AES == operationTable[operHandle].info.alg || + Algorithm::TRIPLE_DES == operationTable[operHandle].info.alg) { + if(ErrorCode::OK != (errorCode = internalUpdate(operHandle, data, len, + opr, out))) { + return errorCode; + } + + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } + } else { + /* Asymmetric */ + if(operationTable[operHandle].info.purpose == KeyPurpose::DECRYPT || + operationTable[operHandle].info.digest == Digest::NONE) { + /* In case of Decrypt, sign with no digest cases buffer the data in + * update call and send data to SE in finish call. + */ + if(finish) { + for(size_t i = 0; i < operationTable[operHandle].data.buf_len; ++i) { + out.push_back(operationTable[operHandle].data.buf[i]); + } + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } + } else { + //Input message length should not be more than the MAX_BUF_SIZE. + if(operationTable[operHandle].data.buf_len <= MAX_BUF_SIZE) { + size_t bufIndex = operationTable[operHandle].data.buf_len; + size_t pos = 0; + for(; (pos < len) && (pos < (MAX_BUF_SIZE-bufIndex)); pos++) + { + operationTable[operHandle].data.buf[bufIndex+pos] = data[pos]; + } + operationTable[operHandle].data.buf_len += pos; + } + } + } else { + for(size_t j=0; j < len; ++j) + { + out.push_back(data[j]); + } + /* if len=0, then no need to call the callback, since there is no information to be send to javacard, + * but if finish flag is true irrespective of length the callback should be called. + */ + if(len != 0 || finish) { + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } + } + } + } + return errorCode; + } }; } // namespace javacard From 84f48bf8105b11038ec4930459715a3f11c0856e Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 21 Jun 2020 02:18:24 +0530 Subject: [PATCH 49/58] Code cleanup Added new method provision Modified importKey functionality --- HAL/keymaster/4.1/CommonUtils.cpp | 227 +++++++++++++++++ .../4.1/JavacardKeymaster4Device.cpp | 239 +++++------------- .../4.1/java_card_soft_keymaster_context.cpp | 158 +----------- HAL/keymaster/Android.bp | 1 + HAL/keymaster/include/CommonUtils.h | 98 +++++++ .../include/JavacardKeymaster4Device.h | 4 + .../java_card_soft_keymaster_context.h | 17 -- 7 files changed, 408 insertions(+), 336 deletions(-) create mode 100644 HAL/keymaster/4.1/CommonUtils.cpp create mode 100644 HAL/keymaster/include/CommonUtils.h diff --git a/HAL/keymaster/4.1/CommonUtils.cpp b/HAL/keymaster/4.1/CommonUtils.cpp new file mode 100644 index 00000000..a4ab2969 --- /dev/null +++ b/HAL/keymaster/4.1/CommonUtils.cpp @@ -0,0 +1,227 @@ +/* + ** + ** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace keymaster { +namespace V4_1 { +namespace javacard { + +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; +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { + keymaster_key_param_set_t set; + + set.params = new keymaster_key_param_t[keyParams.size()]; + set.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: + set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + set.params[i] = keymaster_param_bool(tag); + else + set.params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + set.params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: + set.params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + + return set; +} + +ErrorCode getEcCurve(const EC_GROUP *group, EcCurve& ecCurve) { + int curve = EC_GROUP_get_curve_name(group); + switch(curve) { + case NID_secp224r1: + ecCurve = EcCurve::P_224; + break; + case NID_X9_62_prime256v1: + ecCurve = EcCurve::P_256; + break; + case NID_secp384r1: + ecCurve = EcCurve::P_384; + break; + case NID_secp521r1: + ecCurve = EcCurve::P_521; + break; + default: + return ErrorCode::UNSUPPORTED_EC_CURVE; + } + return ErrorCode::OK; +} + +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector +publicKey, EcCurve& ecCurve) { + UniquePtr pkey; + keymaster_key_blob_t key_material = {pkcs8Blob.data(), pkcs8Blob.size()}; + KeymasterKeyBlob blob(key_material); + ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; + + keymaster_error_t error = KeyMaterialToEvpKey(KM_KEY_FORMAT_PKCS8, blob, KM_ALGORITHM_EC, &pkey); + if(error != KM_ERROR_OK) { + return legacy_enum_conversion(error); + } + UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey.get())); + if(!ec_key.get()) + return legacy_enum_conversion(TranslateLastOpenSslError()); + + //Get EC Group + const EC_GROUP *group = EC_KEY_get0_group(ec_key.get()); + if(group == NULL) + return errorCode; + + if(ErrorCode::OK != (errorCode = getEcCurve(group, ecCurve))) { + return errorCode; + } + + //Extract private key. + const BIGNUM *privBn = EC_KEY_get0_private_key(ec_key.get()); + int privKeyLen = BN_num_bytes(privBn); + std::unique_ptr privKey(new uint8_t[privKeyLen]); + BN_bn2bin(privBn, privKey.get()); + secret.insert(secret.begin(), privKey.get(), privKey.get()+privKeyLen); + + //Extract public key. + const EC_POINT *point = EC_KEY_get0_public_key(ec_key.get()); + int pubKeyLen=0; + pubKeyLen = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + std::unique_ptr pubKey(new uint8_t[pubKeyLen]); + EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, pubKey.get(), pubKeyLen, NULL); + publicKey.insert(publicKey.begin(), pubKey.get(), pubKey.get()+pubKeyLen); + + return ErrorCode::OK; +} + +ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& +pubModulus) { + ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; + const BIGNUM *n=NULL, *e=NULL, *d=NULL; + UniquePtr pkey; + keymaster_key_blob_t key_material = {pkcs8Blob.data(), pkcs8Blob.size()}; + KeymasterKeyBlob blob(key_material); + + keymaster_error_t error = KeyMaterialToEvpKey(KM_KEY_FORMAT_PKCS8, blob, KM_ALGORITHM_RSA, &pkey); + if(error != KM_ERROR_OK) { + return legacy_enum_conversion(error); + } + UniquePtr rsa_key(EVP_PKEY_get1_RSA(pkey.get())); + if(!rsa_key.get()) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + + RSA_get0_key(rsa_key.get(), &n, &e, &d); + if(d != NULL && n != NULL) { + /*private exponent */ + int privExpLen = BN_num_bytes(d); + std::unique_ptr privExp(new uint8_t[privExpLen]); + BN_bn2bin(d, privExp.get()); + /* public modulus */ + int pubModLen = BN_num_bytes(n); + std::unique_ptr pubMod(new uint8_t[pubModLen]); + BN_bn2bin(n, pubMod.get()); + + privateExp.insert(privateExp.begin(), privExp.get(), privExp.get()+privExpLen); + pubModulus.insert(pubModulus.begin(), pubMod.get(), pubMod.get()+pubModLen); + } else { + return errorCode; + } + + return ErrorCode::OK; +} + + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index ef1e4f04..7685c3bf 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -15,14 +15,11 @@ ** limitations under the License. */ -#include #include #include #include #include #include -#include -#include #include #include #include @@ -30,6 +27,7 @@ #include #include +#include //#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" //#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" @@ -70,145 +68,40 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x26, }; -inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { - return static_cast(value); -} - -inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { - return static_cast(value); -} - -inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { - return static_cast(value); -} - -inline keymaster_tag_t legacy_enum_conversion(const Tag value) { - return keymaster_tag_t(value); -} +ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, const hidl_vec& blob, cppbor::Array& + array) { + ErrorCode errorCode = ErrorCode::OK; + AuthorizationSet paramSet; + keymaster_algorithm_t algorithm; -inline Tag legacy_enum_conversion(const keymaster_tag_t value) { - return Tag(value); -} - -inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { - return keymaster_tag_get_type(tag); -} - -keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { - keymaster_key_param_set_t set; - - set.params = new keymaster_key_param_t[keyParams.size()]; - set.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: - set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); - break; - case KM_UINT: - case KM_UINT_REP: - set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); - break; - case KM_ULONG: - case KM_ULONG_REP: - set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); - break; - case KM_DATE: - set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); - break; - case KM_BOOL: - if (keyParams[i].f.boolValue) - set.params[i] = keymaster_param_bool(tag); - else - set.params[i].tag = KM_TAG_INVALID; - break; - case KM_BIGNUM: - case KM_BYTES: - set.params[i] = - keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); - break; - case KM_INVALID: - default: - set.params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; - } - } - - return set; -} + paramSet.Reinitialize(KmParamSet(keyParams)); + paramSet.GetTagValue(TAG_ALGORITHM, &algorithm); -class KmParamSet : public keymaster_key_param_set_t { - public: - explicit KmParamSet(const hidl_vec& keyParams) - : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} - KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { - other.length = 0; - other.params = nullptr; + if(KM_ALGORITHM_RSA == algorithm) { + std::vector privExp; + std::vector modulus; + if(ErrorCode::OK != (errorCode = rsaRawKeyFromPKCS8(std::vector(blob), privExp, modulus))) { + return errorCode; } - KmParamSet(const KmParamSet&) = delete; - ~KmParamSet() { delete[] params; } -}; - -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; + array.add(privExp); + array.add(modulus); + } else if(KM_ALGORITHM_EC == algorithm) { + std::vector privKey; + std::vector pubKey; + EcCurve curve; + if(ErrorCode::OK != (errorCode = ecRawKeyFromPKCS8(std::vector(blob), privKey, pubKey, curve))) { + return errorCode; } + array.add(privKey); + array.add(pubKey); + array.add(static_cast(curve)); + } else { + return ErrorCode::UNSUPPORTED_ALGORITHM; } - return result; -} - -inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { - hidl_vec result; - result.setToExternal(const_cast(buf.peek_read()), buf.available_read()); - return result; -} - -static inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { - for(int i = 0; i < size; ++i) { - to.push_back(from[i]); - } + return errorCode; } -static inline ErrorCode parseWrappedKey(const hidl_vec& wrappedKeyData, std::vector& iv, std::vector& transitKey, +ErrorCode parseWrappedKey(const hidl_vec& wrappedKeyData, std::vector& iv, std::vector& transitKey, std::vector& secureKey, std::vector& tag, hidl_vec& authList, KeyFormat& keyFormat, std::vector& wrappedKeyDescription) { KeymasterBlob kmIv; @@ -509,53 +402,61 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& return Void(); } -Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { - keymaster_error_t error = KM_ERROR_UNKNOWN_ERROR; - hidl_vec inKey; - KeymasterKeyBlob key_material; +Return JavacardKeymaster4Device::provision(const hidl_vec& keyParams, const hidl_vec& +keyData) { + cppbor::Array array; + cppbor::Array subArray; + std::unique_ptr item; + hidl_vec keyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; - if (keyFormat == KeyFormat::PKCS8) { - ImportKeyRequest request; - request.key_description.Reinitialize(KmParamSet(keyParams)); - request.key_format = legacy_enum_conversion(keyFormat); - request.SetKeyMaterial(keyData.data(), keyData.size()); + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyData, subArray))) { + return errorCode; + } + cborConverter_.addKeyparameters(array, keyParams); + array.add(std::move(subArray)); + std::vector cborData = array.encode(); - ImportKeyResponse response; - softKm_->ImportKey(request, &response); + errorCode = sendData(this, pTransportFactory, Instruction::INS_PROVISION_CMD, cborData, cborOutData); - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - error = response.error; - if (response.error == KM_ERROR_OK) { - key_material = KeymasterKeyBlob(response.key_blob); - inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); - } - if(error != KM_ERROR_OK) { - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - _hidl_cb(legacy_enum_conversion(error), resultKeyBlob, resultCharacteristics); - return Void(); - } - } else if (keyFormat == KeyFormat::RAW) { - //convert keyData to keyMaterial - inKey = keyData; - } else { - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - _hidl_cb(legacy_enum_conversion(KM_ERROR_UNSUPPORTED_KEY_FORMAT), resultKeyBlob, resultCharacteristics); - return Void(); + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); } + return errorCode; +} +Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { cppbor::Array array; std::unique_ptr item; hidl_vec keyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; + cppbor::Array subArray; + if(keyFormat != KeyFormat::PKCS8 && keyFormat != KeyFormat::RAW) { + _hidl_cb(ErrorCode::UNSUPPORTED_KEY_FORMAT, keyBlob, keyCharacteristics); + return Void(); + } cborConverter_.addKeyparameters(array, keyParams); - array.add(static_cast(KeyFormat::RAW)); //PKCS8 is already converted to RAW - array.add(std::vector(inKey)); + array.add(static_cast(KeyFormat::RAW)); //javacard accepts only RAW. + if (keyFormat == KeyFormat::PKCS8) { + /* Convert PKCS8 to RAW */ + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyData, subArray))) { + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); + } + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); + } else { + array.add(std::vector(keyData)); + } + std::vector cborData = array.encode(); errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp index 76731d5d..e80d4a0b 100644 --- a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -14,45 +14,23 @@ * limitations under the License. */ -#include - -#include - -#include #include -#include -#include -#include -#include #include +#include #include - -#include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include #include +#include +#include #include -#include -#include -#include -#include -#include - -#include +#include #include -#include -#include - +#include using std::unique_ptr; +using ::keymaster::V4_1::javacard::KmParamSet; namespace keymaster { @@ -61,105 +39,6 @@ JavaCardSoftKeymasterContext::JavaCardSoftKeymasterContext(keymaster_security_le JavaCardSoftKeymasterContext::~JavaCardSoftKeymasterContext() {} -keymaster_error_t JavaCardSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description, - const keymaster_key_origin_t origin, - const KeymasterKeyBlob& key_material, - KeymasterKeyBlob* blob, - AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const { - if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) { - return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE; - } - - keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_, - os_patchlevel_, hw_enforced, sw_enforced); - if (error != KM_ERROR_OK) return error; - - AuthorizationSet hidden; - error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust); - if (error != KM_ERROR_OK) return error; - - size_t size = key_material.SerializedSize(); - - if (!blob->Reset(size)) - return KM_ERROR_MEMORY_ALLOCATION_FAILED; - - uint8_t* p = blob->writable_data(); - p = key_material.Serialize(p, blob->end()); - - return KM_ERROR_OK; -} - -inline keymaster_tag_t legacy_enum_conversion(const Tag value) { - return keymaster_tag_t(value); -} - -inline Tag legacy_enum_conversion(const keymaster_tag_t value) { - return Tag(value); -} - -inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { - return keymaster_tag_get_type(tag); -} - -keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { - keymaster_key_param_set_t set; - - set.params = new keymaster_key_param_t[keyParams.size()]; - set.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: - set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); - break; - case KM_UINT: - case KM_UINT_REP: - set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); - break; - case KM_ULONG: - case KM_ULONG_REP: - set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); - break; - case KM_DATE: - set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); - break; - case KM_BOOL: - if (keyParams[i].f.boolValue) - set.params[i] = keymaster_param_bool(tag); - else - set.params[i].tag = KM_TAG_INVALID; - break; - case KM_BIGNUM: - case KM_BYTES: - set.params[i] = - keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); - break; - case KM_INVALID: - default: - set.params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; - } - } - - return set; -} - -class KmParamSet : public keymaster_key_param_set_t { - public: - explicit KmParamSet(const hidl_vec& keyParams) - : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} - 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; } -}; - EVP_PKEY* RSA_fromMaterial(const uint8_t* modulus, size_t mod_size) { BIGNUM *n = BN_bin2bn(modulus, mod_size, NULL); BIGNUM *e = BN_new();//bignum_decode(exp, 5); @@ -291,31 +170,10 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB std::unique_ptr item; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; std::vector cborKey(blob.key_material_size); -// std::vector cborKey(187); for(size_t i = 0; i < blob.key_material_size; i++) { cborKey[i] = blob.key_material[i]; } -/*uint8_t tempBlob[] = {0x85, 0x58, 0x20, 0xDA, 0x29, 0xC7, 0x1A, 0x8C, 0xE7, 0x6A, 0x0D, 0xFD, -0x2E, 0x53, 0x06, 0x81, 0x85, 0x37, 0x2D, 0x9E, 0x74, 0xE7, 0xF1, 0xD5, -0x3F, 0x0E, 0xAB, 0x1A, 0xF8, 0xE9, 0x46, 0xFD, 0xDC, 0x37, 0x54, 0x4C, -0xE9, 0xA7, 0xD0, 0x71, 0x96, 0xCC, 0x66, 0x18, 0xF0, 0x53, 0xD1, 0x30, -0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x82, 0xA1, 0x1A, 0x30, 0x00, 0x01, 0xF5, 0x1A, 0x01, 0x02, 0x03, -0x04, 0xA6, 0x1A, 0x10, 0x00, 0x00, 0x02, 0x03, 0x1A, 0x50, 0x00, 0x00, -0xC8, 0x1A, 0x00, 0x01, 0x00, 0x01, 0x1A, 0x30, 0x00, 0x00, 0x03, 0x19, -0x01, 0x00, 0x1A, 0x10, 0x00, 0x02, 0xBE, 0x00, 0x1A, 0x30, 0x00, 0x02, -0xC1, 0x00, 0x1A, 0x30, 0x00, 0x02, 0xC2, 0x1A, 0x00, 0x03, 0x15, 0x14, -0x58, 0x41, 0x04, 0x2B, 0xF1, 0x84, 0xD4, 0xFB, 0x63, 0x44, 0x20, 0xD0, -0xA3, 0x7D, 0x6A, 0xC1, 0xC5, 0x26, 0x12, 0xCD, 0x79, 0x77, 0x81, 0x22, -0x33, 0x30, 0x70, 0xF7, 0x25, 0x6D, 0x75, 0xE0, 0xD4, 0xD0, 0x50, 0xD6, -0x80, 0x65, 0x2A, 0x44, 0x0B, 0x8E, 0xFC, 0xA0, 0x8B, 0xC5, 0xF4, 0x8A, -0xCA, 0x4B, 0x89, 0x6E, 0x8B, 0xFC, 0x38, 0xB7, 0xC9, 0xB9, 0xB6, 0xE7, -0x57, 0xE6, 0x53, 0xE9, 0xBF, 0x94, 0x3A}; - for(size_t i = 0; i < 187; i++) { - cborKey[i] = tempBlob[i]; - } -*/ std::tie(item, errorCode) = cc.decodeData(cborKey, false); if (item != nullptr) { std::vector temp; diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 33136850..bd253b43 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -20,6 +20,7 @@ cc_library { "4.1/CborConverter.cpp", "4.1/java_card_soft_keymaster_context.cpp", "4.1/JavacardOperationContext.cpp", + "4.1/CommonUtils.cpp", ], local_include_dirs: [ "include", diff --git a/HAL/keymaster/include/CommonUtils.h b/HAL/keymaster/include/CommonUtils.h new file mode 100644 index 00000000..d7e3cc97 --- /dev/null +++ b/HAL/keymaster/include/CommonUtils.h @@ -0,0 +1,98 @@ +/* + ** + ** 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. + */ + + +#ifndef KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ +#define KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ + +#include +#include +#include + +namespace keymaster { +namespace V4_1 { +namespace javacard { +using ::android::hardware::hidl_vec; +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::Tag; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::EcCurve; + +inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { + return static_cast(value); +} + +inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { + return static_cast(value); +} + +inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { + return static_cast(value); +} + +inline keymaster_tag_t legacy_enum_conversion(const Tag value) { + return keymaster_tag_t(value); +} + +inline Tag legacy_enum_conversion(const keymaster_tag_t value) { + return Tag(value); +} + +inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { + hidl_vec result; + result.setToExternal(const_cast(buf.peek_read()), buf.available_read()); + return result; +} + +inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { + for(int i = 0; i < size; ++i) { + to.push_back(from[i]); + } +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams); + +hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set); + +ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& +pubModulus); + +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector +publicKey, EcCurve& eccurve); + +class KmParamSet : public keymaster_key_param_set_t { + public: + explicit KmParamSet(const hidl_vec& keyParams) + : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} + 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; } +}; + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster +#endif //KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 95299956..68d7c64b 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -85,6 +85,10 @@ class JavacardKeymaster4Device : public IKeymasterDevice { Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; Return earlyBootEnded() override; + //Provision Method + Return provision(const hidl_vec& keyParams, const hidl_vec& + keyData); + //Helper methods. bool getBootParamsInitialized() { return setUpBootParams; } void setBootParams(bool flag) { setUpBootParams = flag; } diff --git a/HAL/keymaster/include/java_card_soft_keymaster_context.h b/HAL/keymaster/include/java_card_soft_keymaster_context.h index 07be5c9e..0fa2d711 100644 --- a/HAL/keymaster/include/java_card_soft_keymaster_context.h +++ b/HAL/keymaster/include/java_card_soft_keymaster_context.h @@ -19,16 +19,6 @@ #include -#include -#include - -#include -#include -#include -#include -#include -#include - namespace keymaster { class SoftKeymasterKeyRegistrations; @@ -53,13 +43,6 @@ class JavaCardSoftKeymasterContext : public keymaster::PureSoftKeymasterContext keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params, UniquePtr* key) const override; - /********************************************************************************************* - * Implement SoftwareKeyBlobMaker - */ - keymaster_error_t CreateKeyBlob(const AuthorizationSet& auths, keymaster_key_origin_t origin, - const KeymasterKeyBlob& key_material, KeymasterKeyBlob* blob, - AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const override; }; From a522bb2ed2e524c5a61045e0c13c8110aeb0605b Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 21 Jun 2020 21:29:46 +0530 Subject: [PATCH 50/58] Fixed issue in importwrappedKey method --- HAL/keymaster/4.1/JavacardKeymaster4Device.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 7685c3bf..d236ccde 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -111,11 +111,12 @@ keyFormat, std::vector& wrappedKeyDescription) { AuthorizationSet authSet; keymaster_key_format_t kmKeyFormat; KeymasterBlob kmWrappedKeyDescription; - KeymasterKeyBlob kmWrappedKeyData; - kmWrappedKeyData.key_material = dup_buffer(wrappedKeyData.data(), wrappedKeyData.size()); + size_t keyDataLen = wrappedKeyData.size(); + uint8_t *keyData = dup_buffer(wrappedKeyData.data(), keyDataLen); + keymaster_key_blob_t keyMaterial = {keyData, keyDataLen}; - keymaster_error_t error = parse_wrapped_key(kmWrappedKeyData, &kmIv, &kmTransitKey, + keymaster_error_t error = parse_wrapped_key(KeymasterKeyBlob(keyMaterial), &kmIv, &kmTransitKey, &kmSecureKey, &kmTag, &authSet, &kmKeyFormat, &kmWrappedKeyDescription); if (error != KM_ERROR_OK) return legacy_enum_conversion(error); @@ -416,7 +417,9 @@ keyData) { return errorCode; } cborConverter_.addKeyparameters(array, keyParams); - array.add(std::move(subArray)); + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); std::vector cborData = array.encode(); errorCode = sendData(this, pTransportFactory, Instruction::INS_PROVISION_CMD, cborData, cborOutData); @@ -494,15 +497,16 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } - array.add(transitKey); - array.add(iv); - array.add(static_cast(keyFormat)); cborConverter_.addKeyparameters(array, authList); + array.add(static_cast(keyFormat)); array.add(secureKey); array.add(tag); + array.add(iv); + array.add(transitKey); array.add(std::vector(wrappingKeyBlob)); array.add(std::vector(maskingKey)); cborConverter_.addKeyparameters(array, unwrappingParams); + array.add(std::vector(wrappedKeyDescription)); array.add(passwordSid); array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); From d4228d714c6ec3c131df19d1c16aceb0ecb70798 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Sun, 21 Jun 2020 22:25:39 +0530 Subject: [PATCH 51/58] Added public operation abort functionality and some fixes in cbor converter. --- HAL/keymaster/4.1/CborConverter.cpp | 12 +++---- .../4.1/JavacardKeymaster4Device.cpp | 31 ++++++++++++------- .../4.1/java_card_soft_keymaster_context.cpp | 21 ++++++++----- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index e7217c2d..62b112b8 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -77,7 +77,7 @@ bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, con bool ret = false; std::unique_ptr arrayItem(nullptr); getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; if (!getKeyParameters(arrayItem, 0, keyCharacteristics.softwareEnforced)) { @@ -229,7 +229,7 @@ bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const std::unique_ptr arrayItem(nullptr); getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; const Array* arr = arrayItem.get()->asArray(); size_t arrSize = arr->size(); @@ -246,7 +246,7 @@ ::android::hardware::hidl_vec& value) { bool ret = false; std::unique_ptr strItem(nullptr); getItemAtPos(item, pos, strItem); - if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + if ((strItem == nullptr) || (MajorType::BSTR != getType(strItem))) return ret; const Bstr* bstr = strItem.get()->asBstr(); @@ -260,7 +260,7 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool ret = false; std::unique_ptr strItem(nullptr); getItemAtPos(item, pos, strItem); - if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + if ((strItem == nullptr) || (MajorType::BSTR != getType(strItem))) return ret; const Bstr* bstr = strItem.get()->asBstr(); @@ -280,7 +280,7 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, //2. First item in the array seed; second item in the array is nonce. getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; //Seed @@ -383,7 +383,7 @@ bool CborConverter::getKeyParameters(const std::unique_ptr& item, const ui std::unique_ptr mapItem(nullptr); std::vector params; getItemAtPos(item, pos, mapItem); - if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) + if ((mapItem == nullptr) || (MajorType::MAP != getType(mapItem))) return ret; const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 7685c3bf..b442876d 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -890,21 +890,30 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi } Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + AbortOperationRequest request; + request.op_handle = operationHandle; - /* Convert input data to cbor format */ - array.add(operationHandle); - std::vector cborData = array.encode(); + AbortOperationResponse response; + softKm_->AbortOperation(request, &response); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = legacy_enum_conversion(response.error); + if (response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); + /* Convert input data to cbor format */ + array.add(operationHandle); + std::vector cborData = array.encode(); + + errorCode = sendData(this, pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + } } /* Delete the entry on this operationHandle */ oprCtx_->clearOperationData(operationHandle); diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp index e80d4a0b..ac638561 100644 --- a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -112,10 +112,17 @@ keymaster_error_t JavaCardSoftKeymasterContext::LoadKey(const keymaster_algorith pkey = RSA_fromMaterial(tmp, temp_size); } else if(algorithm == KM_ALGORITHM_EC) { keymaster_ec_curve_t ec_curve = KM_EC_CURVE_P_256; + uint32_t keySize; if (!hw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve) && !sw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve)) { - return KM_ERROR_INVALID_ARGUMENT; - }//TODO also get ec_curve based on key size + if(!hw_enforced.GetTagValue(TAG_KEY_SIZE, &keySize) && + !sw_enforced.GetTagValue(TAG_KEY_SIZE, &keySize)) { + return KM_ERROR_INVALID_ARGUMENT; + } + error = EcKeySizeToCurve(keySize, &ec_curve); + if(error != KM_ERROR_OK) + return error; + } pkey = EC_fromMaterial(tmp, temp_size, ec_curve); } if (!pkey) @@ -176,11 +183,11 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB } std::tie(item, errorCode) = cc.decodeData(cborKey, false); if (item != nullptr) { - std::vector temp; - cc.getBinaryArray(item, 4, temp); - - key_material = {temp.data(), temp.size()}; - temp.clear(); + std::vector temp(0); + if(cc.getBinaryArray(item, 4, temp)) { + key_material = {temp.data(), temp.size()}; + temp.clear(); + } KeyCharacteristics keyCharacteristics; cc.getKeyCharacteristics(item, 3, keyCharacteristics); From 4e681d103c6c3d959fea69522eb073b561166eb6 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Wed, 24 Jun 2020 17:57:04 +0530 Subject: [PATCH 52/58] Created static instance of TransportFactory so that same will be used in all VTS tests. Also Fixed issue of update operation while AES encryption. --- .../4.1/JavacardKeymaster4Device.cpp | 139 ++++++++++-------- .../4.1/JavacardOperationContext.cpp | 8 +- .../4.1/java_card_soft_keymaster_context.cpp | 7 +- HAL/keymaster/include/CborConverter.h | 2 +- .../include/JavacardKeymaster4Device.h | 1 - .../include/JavacardOperationContext.h | 6 +- 6 files changed, 92 insertions(+), 71 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 8faaf6a6..2ba0b44a 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -40,6 +40,7 @@ namespace keymaster { namespace V4_1 { namespace javacard { +static std::unique_ptr pTransportFactory = nullptr; constexpr size_t kOperationTableSize = 16; enum class Instruction { @@ -68,35 +69,39 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x26, }; -ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, const hidl_vec& blob, cppbor::Array& +ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& blob, cppbor::Array& array) { ErrorCode errorCode = ErrorCode::OK; AuthorizationSet paramSet; keymaster_algorithm_t algorithm; - paramSet.Reinitialize(KmParamSet(keyParams)); - paramSet.GetTagValue(TAG_ALGORITHM, &algorithm); + if(keyFormat == KeyFormat::PKCS8) { - if(KM_ALGORITHM_RSA == algorithm) { - std::vector privExp; - std::vector modulus; - if(ErrorCode::OK != (errorCode = rsaRawKeyFromPKCS8(std::vector(blob), privExp, modulus))) { - return errorCode; - } - array.add(privExp); - array.add(modulus); - } else if(KM_ALGORITHM_EC == algorithm) { - std::vector privKey; - std::vector pubKey; - EcCurve curve; - if(ErrorCode::OK != (errorCode = ecRawKeyFromPKCS8(std::vector(blob), privKey, pubKey, curve))) { - return errorCode; + paramSet.Reinitialize(KmParamSet(keyParams)); + paramSet.GetTagValue(TAG_ALGORITHM, &algorithm); + + if(KM_ALGORITHM_RSA == algorithm) { + std::vector privExp; + std::vector modulus; + if(ErrorCode::OK != (errorCode = rsaRawKeyFromPKCS8(std::vector(blob), privExp, modulus))) { + return errorCode; + } + array.add(privExp); + array.add(modulus); + } else if(KM_ALGORITHM_EC == algorithm) { + std::vector privKey; + std::vector pubKey; + EcCurve curve; + if(ErrorCode::OK != (errorCode = ecRawKeyFromPKCS8(std::vector(blob), privKey, pubKey, curve))) { + return errorCode; + } + array.add(privKey); + array.add(pubKey); + } else { + return ErrorCode::UNSUPPORTED_ALGORITHM; } - array.add(privKey); - array.add(pubKey); - array.add(static_cast(curve)); - } else { - return ErrorCode::UNSUPPORTED_ALGORITHM; + } else if(keyFormat == KeyFormat::RAW) { + array.add(std::vector(blob)); } return errorCode; } @@ -139,9 +144,12 @@ JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::A return context; }(), kOperationTableSize)), oprCtx_(new OperationContext()), setUpBootParams(false) { - pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + + if(pTransportFactory == nullptr) { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( android::base::GetBoolProperty("ro.kernel.qemu", false))); - pTransportFactory->openConnection(); + pTransportFactory->openConnection(); + } } JavacardKeymaster4Device::~JavacardKeymaster4Device() {} @@ -217,13 +225,13 @@ Return setBootParams(std::unique_ptr& return ErrorCode::OK; } -ErrorCode sendData(JavacardKeymaster4Device *pKeymaster, std::unique_ptr& transport, Instruction ins, std::vector& inData, +ErrorCode sendData(JavacardKeymaster4Device *pKeymaster, Instruction ins, std::vector& inData, std::vector& response) { ErrorCode ret = ErrorCode::UNKNOWN_ERROR; std::vector apdu; if(!pKeymaster->getBootParamsInitialized()) { - if((ret = setBootParams(transport)) != ErrorCode::OK) { + if((ret = setBootParams(pTransportFactory)) != ErrorCode::OK) { return ret; } pKeymaster->setBootParams(true); @@ -232,7 +240,7 @@ std::vector& response) { ret = constructApduMessage(ins, inData, apdu); if(ret != ErrorCode::OK) return ret; - if(!transport->sendData(apdu.data(), apdu.size(), response)) { + if(!pTransportFactory->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } @@ -252,7 +260,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); + ErrorCode ret = sendData(this, Instruction::INS_GET_HW_INFO_CMD, input, resp); if((ret == ErrorCode::OK) && (resp.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -279,7 +287,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa HmacSharingParameters hmacSharingParameters; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + errorCode = sendData(this, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -313,7 +321,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -342,7 +350,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -366,7 +374,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec(data)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -388,7 +396,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -413,7 +421,7 @@ keyData) { ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; - if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyData, subArray))) { + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, KeyFormat::PKCS8, keyData, subArray))) { return errorCode; } cborConverter_.addKeyparameters(array, keyParams); @@ -422,7 +430,7 @@ keyData) { array.add(bstr); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_PROVISION_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_PROVISION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -447,22 +455,17 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k } cborConverter_.addKeyparameters(array, keyParams); array.add(static_cast(KeyFormat::RAW)); //javacard accepts only RAW. - if (keyFormat == KeyFormat::PKCS8) { - /* Convert PKCS8 to RAW */ - if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyData, subArray))) { - _hidl_cb(errorCode, keyBlob, keyCharacteristics); - return Void(); - } - std::vector encodedArray = subArray.encode(); - cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); - array.add(bstr); - } else { - array.add(std::vector(keyData)); + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyFormat, keyData, subArray))) { + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); } + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -511,7 +514,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -539,7 +542,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(appData)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -582,7 +585,7 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const h array.add(std::vector(appData)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -608,7 +611,7 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -633,7 +636,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -656,7 +659,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -672,7 +675,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + errorCode = sendData(this, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -688,7 +691,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + errorCode = sendData(this, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -725,6 +728,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cppbor::Array array; std::vector cborOutData; std::unique_ptr item; + std::unique_ptr blobItem = nullptr; + KeyCharacteristics keyCharacteristics; /* Convert input data to cbor format */ array.add(static_cast(purpose)); @@ -733,7 +738,14 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + /* Store the operationInfo */ + std::tie(blobItem, errorCode) = cborConverter_.decodeData(std::vector(keyBlob), false); + + if(blobItem == NULL) { + _hidl_cb(errorCode, outParams, operationHandle); + return Void(); + } + errorCode = sendData(this, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -743,7 +755,10 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getUint64(item, 2, operationHandle); /* Store the operationInfo */ - oprCtx_->setOperationInfo(operationHandle, purpose, inParams); + if (blobItem != nullptr) { + cborConverter_.getKeyCharacteristics(blobItem, 3, keyCharacteristics); + oprCtx_->setOperationInfo(operationHandle, purpose, keyCharacteristics.hardwareEnforced); + } } } _hidl_cb(errorCode, outParams, operationHandle); @@ -786,7 +801,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -868,7 +883,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, ins, cborData, cborOutData); + errorCode = sendData(this, ins, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -911,7 +926,7 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { array.add(operationHandle); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(this, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -937,7 +952,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ErrorCode ret = sendData(this, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -954,7 +969,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + ErrorCode ret = sendData(this, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index b37b4a18..7e242162 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -189,20 +189,20 @@ ErrorCode OperationContext::finish(uint64_t operHandle, const std::vector newInput(first, end); if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, newInput.data(), newInput.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } if(extraData > 0) { std::vector finalInput(input.cend()-extraData, input.cend()); if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, finalInput.data(), finalInput.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } } else { if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, input.data(), input.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } @@ -221,7 +221,7 @@ ErrorCode OperationContext::internalUpdate(uint64_t operHandle, uint8_t* input, int inputConsumed=0; bool dataSendToSE = true; int blockSize = 0; - BufferedData data = operationTable[operHandle].data; + BufferedData& data = operationTable[operHandle].data; int bufIndex = data.buf_len; if(Algorithm::AES == operationTable[operHandle].info.alg) { diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp index ac638561..ba2cba50 100644 --- a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -156,10 +156,13 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB AuthorizationSet hw_enforced; AuthorizationSet sw_enforced; KeymasterKeyBlob key_material; - keymaster_error_t error; + keymaster_error_t error = KM_ERROR_OK; auto constructKey = [&, this] () mutable -> keymaster_error_t { keymaster_algorithm_t algorithm; + if(error != KM_ERROR_OK) { + return error; + } if (!hw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm) && !sw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm)) { return KM_ERROR_INVALID_ARGUMENT; @@ -193,6 +196,8 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB sw_enforced.Reinitialize(KmParamSet(keyCharacteristics.softwareEnforced)); hw_enforced.Reinitialize(KmParamSet(keyCharacteristics.hardwareEnforced)); + } else { + error = KM_ERROR_INVALID_KEY_BLOB; } return constructKey(); } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 08208ee1..65f01b31 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -54,7 +54,7 @@ class CborConverter const uint8_t* pos; std::unique_ptr item(nullptr); std::string message; - T errorCode = T::UNKNOWN_ERROR; + T errorCode = T::OK; std::tie(item, pos, message) = parse(response); diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 68d7c64b..ed9b2dc0 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -95,7 +95,6 @@ class JavacardKeymaster4Device : public IKeymasterDevice { protected: CborConverter cborConverter_; - std::unique_ptr pTransportFactory; private: std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h index d78b1aea..7a6fb706 100644 --- a/HAL/keymaster/include/JavacardOperationContext.h +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -96,9 +96,11 @@ class OperationContext { opr, out))) { return errorCode; } + if(finish || out.size() > 0) { - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } } } else { /* Asymmetric */ From c872a8af9085d1b29ff60b72c327044892474d88 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 25 Jun 2020 17:12:40 +0530 Subject: [PATCH 53/58] 1. Fixed bugs in provision API. Root key extension changed to der. 2. Fixed issue in getMultiBinaryArray in CborConverter class. 3. Added new property keymaster.javacard.provisioned. Based on this property setBootParam and provisioned functions gets called. 4. Added some hard-coded values for attestation IDs inside provision function. --- HAL/keymaster/4.1/CborConverter.cpp | 7 +- HAL/keymaster/4.1/CommonUtils.cpp | 31 +- .../4.1/JavacardKeymaster4Device.cpp | 326 +++++++++++------- HAL/keymaster/include/CborConverter.h | 2 +- .../include/JavacardKeymaster4Device.h | 15 +- 5 files changed, 227 insertions(+), 154 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 62b112b8..22094f28 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -223,8 +223,9 @@ bool CborConverter::getKeyParameter(const std::pair& return ret; } + bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, - ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { + std::vector>& data) { bool ret = false; std::unique_ptr arrayItem(nullptr); @@ -234,8 +235,10 @@ bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const const Array* arr = arrayItem.get()->asArray(); size_t arrSize = arr->size(); for (int i = 0; i < arrSize; i++) { - if (!getBinaryArray(arrayItem, i, data[i])) + std::vector temp; + if (!getBinaryArray(arrayItem, i, temp)) return ret; + data.push_back(std::move(temp)); } ret = true; // success return ret; diff --git a/HAL/keymaster/4.1/CommonUtils.cpp b/HAL/keymaster/4.1/CommonUtils.cpp index a4ab2969..114aca8f 100644 --- a/HAL/keymaster/4.1/CommonUtils.cpp +++ b/HAL/keymaster/4.1/CommonUtils.cpp @@ -144,16 +144,16 @@ ErrorCode getEcCurve(const EC_GROUP *group, EcCurve& ecCurve) { ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector publicKey, EcCurve& ecCurve) { - UniquePtr pkey; - keymaster_key_blob_t key_material = {pkcs8Blob.data(), pkcs8Blob.size()}; - KeymasterKeyBlob blob(key_material); ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; + EVP_PKEY *pkey = nullptr; + const uint8_t *data = pkcs8Blob.data(); - keymaster_error_t error = KeyMaterialToEvpKey(KM_KEY_FORMAT_PKCS8, blob, KM_ALGORITHM_EC, &pkey); - if(error != KM_ERROR_OK) { - return legacy_enum_conversion(error); + d2i_PrivateKey(EVP_PKEY_EC, &pkey, &data, pkcs8Blob.size()); + if(!pkey) { + return legacy_enum_conversion(TranslateLastOpenSslError()); } - UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey.get())); + + UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey)); if(!ec_key.get()) return legacy_enum_conversion(TranslateLastOpenSslError()); @@ -181,6 +181,7 @@ publicKey, EcCurve& ecCurve) { EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, pubKey.get(), pubKeyLen, NULL); publicKey.insert(publicKey.begin(), pubKey.get(), pubKey.get()+pubKeyLen); + EVP_PKEY_free(pkey); return ErrorCode::OK; } @@ -188,15 +189,15 @@ ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector< pubModulus) { ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; const BIGNUM *n=NULL, *e=NULL, *d=NULL; - UniquePtr pkey; - keymaster_key_blob_t key_material = {pkcs8Blob.data(), pkcs8Blob.size()}; - KeymasterKeyBlob blob(key_material); + EVP_PKEY *pkey = nullptr; + const uint8_t *data = pkcs8Blob.data(); - keymaster_error_t error = KeyMaterialToEvpKey(KM_KEY_FORMAT_PKCS8, blob, KM_ALGORITHM_RSA, &pkey); - if(error != KM_ERROR_OK) { - return legacy_enum_conversion(error); + d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &data, pkcs8Blob.size()); + if(!pkey) { + return legacy_enum_conversion(TranslateLastOpenSslError()); } - UniquePtr rsa_key(EVP_PKEY_get1_RSA(pkey.get())); + + UniquePtr rsa_key(EVP_PKEY_get1_RSA(pkey)); if(!rsa_key.get()) { return legacy_enum_conversion(TranslateLastOpenSslError()); } @@ -217,7 +218,7 @@ pubModulus) { } else { return errorCode; } - + EVP_PKEY_free(pkey); return ErrorCode::OK; } diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 2ba0b44a..39cfe74d 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -28,13 +28,16 @@ #include #include #include +#include -//#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" -//#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" #define APDU_CLS 0x80 #define APDU_P1 0x40 #define APDU_P2 0x00 #define APDU_RESP_STATUS_OK 0x9000 +#define ROOT_RSA_KEY "/data/data/rsa_key.der" +#define ROOT_RSA_CERT "/data/data/certificate_rsa.der" +/*This property is used to check if javacard is already provisioned or not */ +#define KM_JAVACARD_PROVISIONED_PROPERTY "keymaster.javacard.provisioned" namespace keymaster { namespace V4_1 { @@ -69,12 +72,19 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x26, }; +static inline std::unique_ptr& getTransportFactoryInstance() { + if(pTransportFactory == nullptr) { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + } + return pTransportFactory; +} + ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& blob, cppbor::Array& array) { ErrorCode errorCode = ErrorCode::OK; AuthorizationSet paramSet; keymaster_algorithm_t algorithm; - if(keyFormat == KeyFormat::PKCS8) { paramSet.Reinitialize(KmParamSet(keyParams)); @@ -136,24 +146,6 @@ keyFormat, std::vector& wrappedKeyDescription) { return ErrorCode::OK; } - -JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( - []() -> auto { - auto context = new JavaCardSoftKeymasterContext(); - context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); - return context; - }(), - kOperationTableSize)), oprCtx_(new OperationContext()), setUpBootParams(false) { - - if(pTransportFactory == nullptr) { - pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( - android::base::GetBoolProperty("ro.kernel.qemu", false))); - pTransportFactory->openConnection(); - } -} - -JavacardKeymaster4Device::~JavacardKeymaster4Device() {} - ErrorCode constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { apduOut.push_back(static_cast(APDU_CLS)); //CLS apduOut.push_back(static_cast(ins)); //INS @@ -192,64 +184,184 @@ uint16_t getStatus(std::vector& inputData) { return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); } -/* This method should be called at the time when HAL is initialized for the first time */ -Return setBootParams(std::unique_ptr& transport) { - cppbor::Array array; - std::vector apdu; - std::vector response; - Instruction ins = Instruction::INS_SET_BOOT_PARAMS_CMD; +bool readDataFromFile(const char *filename, std::vector& data) { + FILE *fp; + bool ret = true; + fp = fopen(filename, "rb"); + if(fp == NULL) { + LOG(ERROR) << "Failed to open file: " << filename; + return false; + } + fseek(fp, 0L, SEEK_END); + long int filesize = ftell(fp); + rewind(fp); + std::unique_ptr buf(new uint8_t[filesize]); + if( 0 == fread(buf.get(), filesize, 1, fp)) { + LOG(ERROR) << "No Content in the file: " << filename; + ret = false; + } + if(true == ret) { + data.insert(data.begin(), buf.get(), buf.get() + filesize); + } + fclose(fp); + return ret; +} + +ErrorCode initiateProvision() { + /* This is just a reference implemenation */ + std::string brand("Google"); + std::string device("Pixel 3A"); + std::string product("Pixel"); + std::string serial("UGYJFDjFeRuBEH"); + std::string imei("987080543071019"); + std::string meid("27863510227963"); + std::string manufacturer("Foxconn"); + std::string model("HD1121"); + AuthorizationSet authSet(AuthorizationSetBuilder() + .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA) + .Authorization(TAG_ATTESTATION_ID_BRAND, brand.data(), brand.size()) + .Authorization(TAG_ATTESTATION_ID_DEVICE, device.data(), device.size()) + .Authorization(TAG_ATTESTATION_ID_PRODUCT, product.data(), product.size()) + .Authorization(TAG_ATTESTATION_ID_SERIAL, serial.data(), serial.size()) + .Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size()) + .Authorization(TAG_ATTESTATION_ID_MEID, meid.data(), meid.size()) + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, manufacturer.data(), manufacturer.size()) + .Authorization(TAG_ATTESTATION_ID_MODEL, model.data(), model.size())); + + hidl_vec keyParams = kmParamSet2Hidl(authSet); + std::vector data; + if(!readDataFromFile(ROOT_RSA_KEY, data)) { + LOG(ERROR) << " Failed to read the Root rsa key"; + return ErrorCode::UNKNOWN_ERROR; + } + return JavacardKeymaster4Device::provision(keyParams, KeyFormat::PKCS8, data); +} + +Return setBootParams() { std::vector verifiedBootKey(32, 0); std::vector verifiedBootKeyHash(32, 0); - array.add(GetOsVersion()). - add(GetOsPatchlevel()). - /* Verified Boot Key */ - add(verifiedBootKey). - /* Verified Boot Hash */ - add(verifiedBootKeyHash). - /* boot state */ - add(static_cast(KM_VERIFIED_BOOT_UNVERIFIED)). - /* device locked */ - add(0); /* false */ - std::vector cborData = array.encode(); - ErrorCode ret = constructApduMessage(ins, cborData, apdu); + return JavacardKeymaster4Device::setBootParams(GetOsVersion(), GetOsPatchlevel(), verifiedBootKey, verifiedBootKeyHash, + KM_VERIFIED_BOOT_UNVERIFIED, 0/*deviceLocked*/); +} + +ErrorCode sendData(Instruction ins, std::vector& inData, std::vector& response) { + ErrorCode ret = ErrorCode::UNKNOWN_ERROR; + std::vector apdu; + + if(!android::base::GetBoolProperty(KM_JAVACARD_PROVISIONED_PROPERTY, false)) { + if(ErrorCode::OK != (ret = setBootParams())) { + LOG(ERROR) << "Failed to set boot params"; + return ret; + } + + if(ErrorCode::OK != (ret = initiateProvision())) { + LOG(ERROR) << "Failed to provision the device"; + return ret; + } + android::base::SetProperty(KM_JAVACARD_PROVISIONED_PROPERTY, "true"); + } + + ret = constructApduMessage(ins, inData, apdu); if(ret != ErrorCode::OK) return ret; - if(!transport->sendData(apdu.data(), apdu.size(), response)) { + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { return (ErrorCode::UNKNOWN_ERROR); } - return ErrorCode::OK; + return (ErrorCode::OK);//success } -ErrorCode sendData(JavacardKeymaster4Device *pKeymaster, Instruction ins, std::vector& inData, -std::vector& response) { - ErrorCode ret = ErrorCode::UNKNOWN_ERROR; +ErrorCode JavacardKeymaster4Device::provision(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& +keyData) { + cppbor::Array array; + cppbor::Array subArray; + std::unique_ptr item; std::vector apdu; + hidl_vec keyBlob; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + Instruction ins = Instruction::INS_PROVISION_CMD; + std::vector response; + CborConverter cborConverter; - if(!pKeymaster->getBootParamsInitialized()) { - if((ret = setBootParams(pTransportFactory)) != ErrorCode::OK) { - return ret; - } - pKeymaster->setBootParams(true); + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyFormat, keyData, subArray))) { + return errorCode; + } + /* construct cbor */ + cborConverter.addKeyparameters(array, keyParams); + array.add(static_cast(keyFormat)); + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); + std::vector cborData = array.encode(); + + if(ErrorCode::OK != (errorCode = constructApduMessage(ins, cborData, apdu))) + return errorCode; + + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } - ret = constructApduMessage(ins, inData, apdu); + if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { + return (ErrorCode::UNKNOWN_ERROR); + } + + if((response.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter.decodeData(std::vector(response.begin(), response.end()-2), + true); + } + return errorCode; +} + +ErrorCode JavacardKeymaster4Device::setBootParams(uint32_t osVersion, uint32_t osPatchLevel, const std::vector& verifiedBootKey, +std::vector& verifiedBootKeyHash, keymaster_verified_boot_t kmVerifiedBoot, bool deviceLocked) { + cppbor::Array array; + std::vector apdu; + std::vector response; + Instruction ins = Instruction::INS_SET_BOOT_PARAMS_CMD; + array.add(osVersion). + add(osPatchLevel). + /* Verified Boot Key */ + add(verifiedBootKey). + /* Verified Boot Hash */ + add(verifiedBootKeyHash). + /* boot state */ + add(static_cast(kmVerifiedBoot)). + /* device locked */ + add(static_cast(deviceLocked)); + std::vector cborData = array.encode(); + + ErrorCode ret = constructApduMessage(ins, cborData, apdu); if(ret != ErrorCode::OK) return ret; - if(!pTransportFactory->sendData(apdu.data(), apdu.size(), response)) { + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { return (ErrorCode::UNKNOWN_ERROR); } - return (ErrorCode::OK);//success + return ErrorCode::OK; + +} + +JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( + []() -> auto { + auto context = new JavaCardSoftKeymasterContext(); + context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); + return context; + }(), + kOperationTableSize)), oprCtx_(new OperationContext()) { + + getTransportFactoryInstance()->openConnection(); } +JavacardKeymaster4Device::~JavacardKeymaster4Device() {} + // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); @@ -260,7 +372,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - ErrorCode ret = sendData(this, Instruction::INS_GET_HW_INFO_CMD, input, resp); + ErrorCode ret = sendData(Instruction::INS_GET_HW_INFO_CMD, input, resp); if((ret == ErrorCode::OK) && (resp.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -287,7 +399,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa HmacSharingParameters hmacSharingParameters; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + errorCode = sendData(Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -321,7 +433,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -350,7 +462,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -374,7 +486,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec(data)); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -396,7 +508,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -411,35 +523,6 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& return Void(); } -Return JavacardKeymaster4Device::provision(const hidl_vec& keyParams, const hidl_vec& -keyData) { - cppbor::Array array; - cppbor::Array subArray; - std::unique_ptr item; - hidl_vec keyBlob; - std::vector cborOutData; - ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - KeyCharacteristics keyCharacteristics; - - if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, KeyFormat::PKCS8, keyData, subArray))) { - return errorCode; - } - cborConverter_.addKeyparameters(array, keyParams); - std::vector encodedArray = subArray.encode(); - cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); - array.add(bstr); - std::vector cborData = array.encode(); - - errorCode = sendData(this, Instruction::INS_PROVISION_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - } - return errorCode; -} - Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { cppbor::Array array; std::unique_ptr item; @@ -454,7 +537,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k return Void(); } cborConverter_.addKeyparameters(array, keyParams); - array.add(static_cast(KeyFormat::RAW)); //javacard accepts only RAW. + array.add(static_cast(KeyFormat::RAW)); //javacard accepts only RAW. if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyFormat, keyData, subArray))) { _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); @@ -465,7 +548,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -514,7 +597,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -542,7 +625,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(appData)); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -561,7 +644,6 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const h ExportKeyRequest request; request.key_format = legacy_enum_conversion(exportFormat); request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); - //addClientAndAppData(clientId, appData, &request.additional_params); ExportKeyResponse response; softKm_->ExportKey(request, &response); @@ -572,31 +654,6 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const h } _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob); return Void(); -/* - cppbor::Array array; - std::unique_ptr item; - hidl_vec keyMaterial; - std::vector cborOutData; - ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - - array.add(static_cast(exportFormat)); - array.add(std::vector(keyBlob)); - array.add(std::vector(clientId)); - array.add(std::vector(appData)); - std::vector cborData = array.encode(); - - errorCode = sendData(this, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getBinaryArray(item, 1, keyMaterial); - } - } - _hidl_cb(errorCode, keyMaterial); - return Void();*/ } Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { @@ -611,14 +668,25 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + std::vector> temp; + std::vector rootCert; //Skip last 2 bytes in cborData, it contains status. std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - cborConverter_.getMultiBinaryArray(item, 1, certChain); + cborConverter_.getMultiBinaryArray(item, 1, temp); + } + if(readDataFromFile(ROOT_RSA_CERT, rootCert)) { + temp.push_back(std::move(rootCert)); + certChain.resize(temp.size()); + for(int i = 0; i < temp.size(); i++) { + certChain[i] = temp[i]; + } + } else { + LOG(ERROR) << "No root certificate found"; } } _hidl_cb(errorCode, certChain); @@ -636,7 +704,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -659,7 +727,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -675,7 +743,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + errorCode = sendData(Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -691,7 +759,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + errorCode = sendData(Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -745,7 +813,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< _hidl_cb(errorCode, outParams, operationHandle); return Void(); } - errorCode = sendData(this, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -801,7 +869,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -883,7 +951,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi cborConverter_.addVerificationToken(array, verificationToken); std::vector cborData = array.encode(); - errorCode = sendData(this, ins, cborData, cborOutData); + errorCode = sendData(ins, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -926,7 +994,7 @@ Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { array.add(operationHandle); std::vector cborData = array.encode(); - errorCode = sendData(this, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -952,7 +1020,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - ErrorCode ret = sendData(this, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ErrorCode ret = sendData(Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -969,7 +1037,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - ErrorCode ret = sendData(this, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + ErrorCode ret = sendData(Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 65f01b31..c591926a 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -138,7 +138,7 @@ class CborConverter * Get the list of binary arrays at the given position from the item pointer. */ bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, - ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data); + std::vector>& data); /** * Add VerificationToken value to the Array item. diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index ed9b2dc0..c7c06ed5 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -85,13 +85,15 @@ class JavacardKeymaster4Device : public IKeymasterDevice { Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; Return earlyBootEnded() override; - //Provision Method - Return provision(const hidl_vec& keyParams, const hidl_vec& - keyData); + //Set Boot Params + /* This method should be called at the time when HAL is initialized for the first time */ + static ErrorCode setBootParams(uint32_t osVersion, uint32_t osPatchLevel, const std::vector& verifiedBootKey, +std::vector& verifiedBootKeyHash, keymaster_verified_boot_t kmVerifiedBoot, bool deviceLocked); - //Helper methods. - bool getBootParamsInitialized() { return setUpBootParams; } - void setBootParams(bool flag) { setUpBootParams = flag; } + //Provision Method + /* Reference for vendor to provision the javacard. This should happen only once at the time of production.*/ + static ErrorCode provision(const hidl_vec& keyParams, KeyFormat keyformat, const hidl_vec& +keyData); protected: CborConverter cborConverter_; @@ -99,7 +101,6 @@ class JavacardKeymaster4Device : public IKeymasterDevice { private: std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; std::unique_ptr oprCtx_; - bool setUpBootParams; }; } // namespace javacard From a354827d19120a8f1135c06e225cf75e391c5a52 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 29 Jun 2020 03:24:12 +0530 Subject: [PATCH 54/58] Encode the parametersVerified value inside VerficationToken to asn1 format before sending to javacard. --- HAL/keymaster/4.1/CborConverter.cpp | 5 +- .../4.1/JavacardKeymaster4Device.cpp | 62 +++++++++++++++++-- HAL/keymaster/include/CborConverter.h | 2 +- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 22094f28..345c43a1 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -299,13 +299,10 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, } bool CborConverter::addVerificationToken(Array& array, const VerificationToken& - verificationToken) { - std::vector encodedParamsVerified; + verificationToken, std::vector& encodedParamsVerified) { Array vToken; vToken.add(verificationToken.challenge); vToken.add(verificationToken.timestamp); - //addKeyparameters(vToken, verificationToken.parametersVerified); - /* TODO Need to get proper encodedParamsVerified */ vToken.add(std::move(encodedParamsVerified)); vToken.add(static_cast(verificationToken.securityLevel)); vToken.add((std::vector(verificationToken.mac))); diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 39cfe74d..233154cb 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -46,6 +48,10 @@ namespace javacard { static std::unique_ptr pTransportFactory = nullptr; constexpr size_t kOperationTableSize = 16; +struct KM_AUTH_LIST_Delete { + void operator()(KM_AUTH_LIST* p) { KM_AUTH_LIST_free(p); } +}; + enum class Instruction { INS_GENERATE_KEY_CMD = 0x10, INS_IMPORT_KEY_CMD = 0x11, @@ -80,6 +86,38 @@ static inline std::unique_ptr& getTransportFacto return pTransportFactory; } +ErrorCode encodeParametersVerified(const VerificationToken& verificationToken, std::vector asn1ParamsVerified) { + if (verificationToken.parametersVerified.size() > 0) { + AuthorizationSet paramSet; + KeymasterBlob derBlob; + UniquePtr kmAuthList(KM_AUTH_LIST_new()); + + paramSet.Reinitialize(KmParamSet(verificationToken.parametersVerified)); + + auto err = build_auth_list(paramSet, kmAuthList.get()); + if (err != KM_ERROR_OK) { + return legacy_enum_conversion(err); + } + int len = i2d_KM_AUTH_LIST(kmAuthList.get(), nullptr); + if (len < 0) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + + if (!derBlob.Reset(len)) { + return legacy_enum_conversion(KM_ERROR_MEMORY_ALLOCATION_FAILED); + } + + uint8_t* p = derBlob.writable_data(); + len = i2d_KM_AUTH_LIST(kmAuthList.get(), &p); + if (len < 0) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + asn1ParamsVerified.insert(asn1ParamsVerified.begin(), p, p+len); + derBlob.release(); + } + return ErrorCode::OK; +} + ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& blob, cppbor::Array& array) { ErrorCode errorCode = ErrorCode::OK; @@ -860,13 +898,18 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cppbor::Array array; std::unique_ptr item; std::vector cborOutData; + std::vector asn1ParamsVerified; + + if(ErrorCode::OK != (errorCode = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } // Convert input data to cbor format array.add(operationHandle); cborConverter_.addKeyparameters(array, inParams); array.add(data); cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); errorCode = sendData(Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); @@ -932,6 +975,11 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi std::unique_ptr item; std::vector cborOutData; int keyParamPos, outputPos; + std::vector asn1ParamsVerified; + + if(ErrorCode::OK != (errorCode = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } // Convert input data to cbor format array.add(operationHandle); @@ -948,7 +996,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi outputPos = 3; } cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); errorCode = sendData(ins, cborData, cborOutData); @@ -1013,14 +1061,20 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::unique_ptr item; std::vector cborOutData; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + std::vector asn1ParamsVerified; + ErrorCode ret = ErrorCode::UNKNOWN_ERROR; + + if(ErrorCode::OK != (ret = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } /* Convert input data to cbor format */ array.add(passwordOnly); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - ErrorCode ret = sendData(Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ret = sendData(Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index c591926a..9ea2ef94 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -144,7 +144,7 @@ class CborConverter * Add VerificationToken value to the Array item. */ bool addVerificationToken(Array& array, const VerificationToken& - verificationToken); + verificationToken, std::vector& encodedParamsVerified); /** * Get the ErrorCode value at the give position from the item pointer. From 969fc8379424faf0eec4f649bdb955f792e59974 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Tue, 30 Jun 2020 15:56:59 +0530 Subject: [PATCH 55/58] Fixed issue of empty public key in EC key extract. Also returned error if empty key blob is sent to begin function. --- HAL/keymaster/4.1/CommonUtils.cpp | 2 +- HAL/keymaster/4.1/JavacardKeymaster4Device.cpp | 9 +++++++-- HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp | 2 +- HAL/keymaster/include/CommonUtils.h | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/HAL/keymaster/4.1/CommonUtils.cpp b/HAL/keymaster/4.1/CommonUtils.cpp index 114aca8f..67993957 100644 --- a/HAL/keymaster/4.1/CommonUtils.cpp +++ b/HAL/keymaster/4.1/CommonUtils.cpp @@ -142,7 +142,7 @@ ErrorCode getEcCurve(const EC_GROUP *group, EcCurve& ecCurve) { return ErrorCode::OK; } -ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& publicKey, EcCurve& ecCurve) { ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; EVP_PKEY *pkey = nullptr; diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 233154cb..13cddd78 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -82,6 +82,7 @@ static inline std::unique_ptr& getTransportFacto if(pTransportFactory == nullptr) { pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( android::base::GetBoolProperty("ro.kernel.qemu", false))); + pTransportFactory->openConnection(); } return pTransportFactory; } @@ -395,7 +396,6 @@ JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::A }(), kOperationTableSize)), oprCtx_(new OperationContext()) { - getTransportFactoryInstance()->openConnection(); } JavacardKeymaster4Device::~JavacardKeymaster4Device() {} @@ -811,6 +811,12 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; hidl_vec outParams; uint64_t operationHandle = 0; + hidl_vec resultParams; + + if(keyBlob.size() == 0) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, resultParams, operationHandle); + return Void(); + } if (KeyPurpose::ENCRYPT == purpose || KeyPurpose::VERIFY == purpose) { BeginOperationRequest request; @@ -821,7 +827,6 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< BeginOperationResponse response; softKm_->BeginOperation(request, &response); - hidl_vec resultParams; if (response.error == KM_ERROR_OK) { resultParams = kmParamSet2Hidl(response.output_params); } diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp index ba2cba50..1186b398 100644 --- a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -111,7 +111,7 @@ keymaster_error_t JavaCardSoftKeymasterContext::LoadKey(const keymaster_algorith if(algorithm == KM_ALGORITHM_RSA) { pkey = RSA_fromMaterial(tmp, temp_size); } else if(algorithm == KM_ALGORITHM_EC) { - keymaster_ec_curve_t ec_curve = KM_EC_CURVE_P_256; + keymaster_ec_curve_t ec_curve; uint32_t keySize; if (!hw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve) && !sw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve)) { diff --git a/HAL/keymaster/include/CommonUtils.h b/HAL/keymaster/include/CommonUtils.h index d7e3cc97..a3feee14 100644 --- a/HAL/keymaster/include/CommonUtils.h +++ b/HAL/keymaster/include/CommonUtils.h @@ -77,7 +77,7 @@ hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set); ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& pubModulus); -ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& publicKey, EcCurve& eccurve); class KmParamSet : public keymaster_key_param_set_t { From eeb5d6326ef2afd52227d81a3310aa44121b4a5c Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 1 Jul 2020 02:46:09 +0530 Subject: [PATCH 56/58] Fixed the issue while parsing the Keyparameters from cbor --- HAL/keymaster/4.1/CborConverter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 345c43a1..1d22b6e8 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -209,9 +209,9 @@ bool CborConverter::getKeyParameter(const std::pair& { KeyParameter keyParam; keyParam.tag = static_cast(key); - if(!getBinaryArray(pair.second, 0, keyParam.blob)) { - return ret; - } + const Bstr* bstr = pair.second.get()->asBstr(); + if(bstr == nullptr) return ret; + keyParam.blob = bstr->value(); keyParams.push_back(std::move(keyParam)); return true; } From 918859d74677f1015c9a3a7a4ffef54d89725149 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 1 Jul 2020 16:04:07 +0530 Subject: [PATCH 57/58] Added Digest, Padding, Keysize in Param list in provision API --- HAL/keymaster/4.1/JavacardKeymaster4Device.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 13cddd78..c0293756 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -258,6 +258,10 @@ ErrorCode initiateProvision() { std::string model("HD1121"); AuthorizationSet authSet(AuthorizationSetBuilder() .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA) + .Authorization(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN) + .Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256) + .Authorization(TAG_KEY_SIZE, 2048) + .Authorization(TAG_PURPOSE, static_cast(0x7F)) /* The value 0x7F is not present in types.hal */ .Authorization(TAG_ATTESTATION_ID_BRAND, brand.data(), brand.size()) .Authorization(TAG_ATTESTATION_ID_DEVICE, device.data(), device.size()) .Authorization(TAG_ATTESTATION_ID_PRODUCT, product.data(), product.size()) From 35fac600d88da4fdb64043c9ca7cf1f81f4ace77 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 1 Jul 2020 19:42:15 +0530 Subject: [PATCH 58/58] 1. Fix for TOO_MANY_OPERATIONS 2. Comment notes --- .../4.1/JavacardKeymaster4Device.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index c0293756..7e04681a 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -853,10 +853,13 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - /* Store the operationInfo */ + /* keyCharacteristics.hardwareEnforced is required to store algorithm, digest and padding values in operationInfo + * structure. To retrieve keyCharacteristics.hardwareEnforced, parse the keyBlob. + */ + /* TODO if keyBlob is corrupted it crashes in cbor */ std::tie(blobItem, errorCode) = cborConverter_.decodeData(std::vector(keyBlob), false); - if(blobItem == NULL) { + if(blobItem == nullptr) { _hidl_cb(errorCode, outParams, operationHandle); return Void(); } @@ -870,10 +873,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getUint64(item, 2, operationHandle); /* Store the operationInfo */ - if (blobItem != nullptr) { - cborConverter_.getKeyCharacteristics(blobItem, 3, keyCharacteristics); - oprCtx_->setOperationInfo(operationHandle, purpose, keyCharacteristics.hardwareEnforced); - } + cborConverter_.getKeyCharacteristics(blobItem, 3, keyCharacteristics); + oprCtx_->setOperationInfo(operationHandle, purpose, keyCharacteristics.hardwareEnforced); } } _hidl_cb(errorCode, outParams, operationHandle); @@ -945,8 +946,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi } } if(ErrorCode::OK != errorCode) { - /* Delete the entry on this operationHandle */ - oprCtx_->clearOperationData(operationHandle); + abort(operationHandle); } _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); @@ -1027,8 +1027,7 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi output = tempOut; } } - /* Delete the entry on this operationHandle */ - oprCtx_->clearOperationData(operationHandle); + abort(operationHandle); _hidl_cb(errorCode, outParams, output); return Void(); }