From 84f48bf8105b11038ec4930459715a3f11c0856e Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Sun, 21 Jun 2020 02:18:24 +0530 Subject: [PATCH 01/10] 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 02/10] 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 03/10] 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 04/10] 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 05/10] 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 06/10] 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 07/10] 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 08/10] 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 09/10] 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 10/10] 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(); }