From 86f132073438db0d2ab0b29c10460090f91e139f Mon Sep 17 00:00:00 2001 From: Venkateswarlu Bhamidipati Date: Thu, 26 Aug 2021 20:03:35 +0000 Subject: [PATCH 1/2] Removed gpapi-upgrade.jar. Refer to README.txt to see how to download --- Applet/AndroidSEProvider/lib/gpapi-upgrade.jar | Bin 12638 -> 0 bytes Applet/JCardSimProvider/lib/gpapi-upgrade.jar | Bin 12638 -> 0 bytes Applet/README.md | 1 + 3 files changed, 1 insertion(+) delete mode 100644 Applet/AndroidSEProvider/lib/gpapi-upgrade.jar delete mode 100644 Applet/JCardSimProvider/lib/gpapi-upgrade.jar diff --git a/Applet/AndroidSEProvider/lib/gpapi-upgrade.jar b/Applet/AndroidSEProvider/lib/gpapi-upgrade.jar deleted file mode 100644 index e4814bde4b6b21982103c55f9b1a3a4a58f0b807..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12638 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 I@K+`Of52({3;+NC diff --git a/Applet/JCardSimProvider/lib/gpapi-upgrade.jar b/Applet/JCardSimProvider/lib/gpapi-upgrade.jar deleted file mode 100644 index e4814bde4b6b21982103c55f9b1a3a4a58f0b807..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12638 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 I@K+`Of52({3;+NC diff --git a/Applet/README.md b/Applet/README.md index 76af5b05..3a859194 100644 --- a/Applet/README.md +++ b/Applet/README.md @@ -17,3 +17,4 @@ which serves to intermediate between Android Keystore and this applet. - Install Javacard 3.0.5 classic sdk. - set JC_HOME_SIMULATOR environment variable to the installed sdk. - Give ant build from Applet folder. +- Download [gpapi-upgrade.jar](https://globalplatform.wpengine.com/specs-library/globalplatform-card-api-org-globalplatform-upgrade-v1/) and copy inside lib folder of both AndroidSEProvider and JCardSimProvider to resolve the compilation errors. From b6a5f1aa3d07a5470f104cbf92b56eacb476c898 Mon Sep 17 00:00:00 2001 From: Venkateswarlu Bhamidipati Date: Thu, 26 Aug 2021 20:33:22 +0000 Subject: [PATCH 2/2] Fix for the issue that operation handle(i.e Challenge), inside the HardwareAuthToken and VerificationToken is mismatching with the operation handle generated by Strongbox. --- .../4.1/JavacardKeymaster4Device.cpp | 400 ++++++++++-------- .../include/JavacardKeymaster4Device.h | 38 +- 2 files changed, 271 insertions(+), 167 deletions(-) diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 67f8f527..95de2096 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -59,10 +59,11 @@ namespace javacard { static std::unique_ptr pTransportFactory = nullptr; constexpr size_t kOperationTableSize = 4; -/* Key is the newly generated operation handle. Value is a pair with first element having - * original operation handle and second element represents SW or SB operation. +/* + * Key is the operation handle generated by either SoftKM or StrongboxKM and + * value is either PUBLIC_OPERATION or PRIVATE_OPERATION */ -std::map> operationTable; +std::map operationTable; struct KM_AUTH_LIST_Delete { void operator()(KM_AUTH_LIST* p) { KM_AUTH_LIST_free(p); } @@ -183,51 +184,20 @@ static T translateExtendedErrorsToHalErrors(T& errorCode) { return err; } -/* Generate new operation handle */ -static ErrorCode generateOperationHandle(uint64_t& oprHandle) { - std::map>::iterator it; - do { - keymaster_error_t err = GenerateRandom(reinterpret_cast(&oprHandle), (size_t)sizeof(oprHandle)); - if (err != KM_ERROR_OK) { - return legacy_enum_conversion(err); - } - it = operationTable.find(oprHandle); - } while (it != operationTable.end()); - return ErrorCode::OK; -} - -/* Create a new operation handle entry in operation table.*/ -static ErrorCode createOprHandleEntry(uint64_t origOprHandle, uint64_t keymasterSrc, uint64_t& newOperationHandle) { - ErrorCode errorCode = ErrorCode::OK; - if (ErrorCode::OK != (errorCode = generateOperationHandle(newOperationHandle))) { - return errorCode; - } - operationTable[newOperationHandle] = std::make_pair(origOprHandle, keymasterSrc); - return errorCode; -} - -/* Get original operation handle generated by softkeymaster/strongboxkeymaster. */ -static ErrorCode getOrigOperationHandle(uint64_t halGeneratedOperationHandle, uint64_t& origOprHandle) { - std::map>::iterator it = operationTable.find(halGeneratedOperationHandle); - if (it == operationTable.end()) { - return ErrorCode::INVALID_OPERATION_HANDLE; +/* Returns true if operation handle exists, otherwise false */ +static inline bool isOperationHandleExists(uint64_t opHandle) { + if (operationTable.end() == operationTable.find(opHandle)) { + return false; } - origOprHandle = it->second.first; - return ErrorCode::OK; + return true; } -/* Tells if the operation handle belongs to strongbox keymaster. */ -static bool isStrongboxOperation(uint64_t halGeneratedOperationHandle) { - std::map>::iterator it = operationTable.find(halGeneratedOperationHandle); +static inline OperationType getOperationType(uint64_t operationHandle) { + auto it = operationTable.find(operationHandle); if (it == operationTable.end()) { - return false; + return OperationType::UNKNOWN; } - return (SB_KM_OPR == it->second.second); -} - -/* Delete the operation handle entry from operation table. */ -static void deleteOprHandleEntry(uint64_t halGeneratedOperationHandle) { - operationTable.erase(halGeneratedOperationHandle); + return it->second; } /* Clears all the strongbox operation handle entries from operation table */ @@ -235,9 +205,9 @@ static void clearStrongboxOprHandleEntries(const std::unique_ptrsecond.second == SB_KM_OPR) { //Strongbox operation + if (it->second == OperationType::PRIVATE_OPERATION) { //Strongbox operation LOG(INFO) << "operation handle: " << it->first << " is removed"; - oprCtx->clearOperationData(it->second.first); + oprCtx->clearOperationData(it->first); it = operationTable.erase(it); } else { ++it; @@ -1026,55 +996,97 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { return errorCode; } -Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec& inParams, const HardwareAuthToken& authToken, begin_cb _hidl_cb) { + +Return JavacardKeymaster4Device::begin(KeyPurpose purpose, + const hidl_vec& keyBlob, + const hidl_vec& inParams, + const HardwareAuthToken& authToken, + begin_cb _hidl_cb) { ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - hidl_vec outParams; uint64_t operationHandle = 0; - hidl_vec resultParams; - uint64_t generatedOpHandle = 0; - - if(keyBlob.size() == 0) { - LOG(ERROR) << "Error in INS_BEGIN_OPERATION_CMD, keyblob size is 0"; - _hidl_cb(ErrorCode::INVALID_ARGUMENT, resultParams, operationHandle); - return Void(); - } - /* Asymmetric public key operations like RSA Verify, RSA Encrypt, ECDSA verify - * are handled by softkeymaster. + OperationType operType = OperationType::PRIVATE_OPERATION; + hidl_vec outParams; + LOG(DEBUG) << "INS_BEGIN_OPERATION_CMD purpose: " << (int32_t)purpose; + /* + * Asymmetric public key operations are processed inside softkeymaster and private + * key operations are processed inside strongbox keymaster. + * All symmetric key operations are processed inside strongbox keymaster. + * If the purpose is either ENCRYPT / VERIFY then the operation type is set + * to public operation and in case if the key turned out to be a symmetric key then + * handleBeginOperation() function fallbacks to private key operation. */ LOG(DEBUG) << "INS_BEGIN_OPERATION_CMD purpose: " << (int32_t)purpose; if (KeyPurpose::ENCRYPT == purpose || KeyPurpose::VERIFY == purpose) { - BeginOperationRequest request; - request.purpose = legacy_enum_conversion(purpose); - request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); - request.additional_params.Reinitialize(KmParamSet(inParams)); - - BeginOperationResponse response; - /* For Symmetric key operation, the BeginOperation returns KM_ERROR_INCOMPATIBLE_ALGORITHM error. */ - softKm_->BeginOperation(request, &response); - errorCode = legacy_enum_conversion(response.error); - LOG(DEBUG) << "INS_BEGIN_OPERATION_CMD softkm BeginOperation status: " << (int32_t) errorCode; - if (errorCode != ErrorCode::OK) - LOG(ERROR) << "INS_BEGIN_OPERATION_CMD error in softkm BeginOperation status: " << (int32_t) errorCode; - - if (response.error == KM_ERROR_OK) { - resultParams = kmParamSet2Hidl(response.output_params); - } - if (response.error != KM_ERROR_INCOMPATIBLE_ALGORITHM) { /*Incompatible algorithm could be handled by JavaCard*/ - errorCode = legacy_enum_conversion(response.error); - /* Create a new operation handle and add a entry inside the operation table map with - * key - new operation handle - * value - hal generated operation handle. - */ - if (errorCode == ErrorCode::OK) { - errorCode = createOprHandleEntry(response.op_handle, SW_KM_OPR, generatedOpHandle); - if (errorCode != ErrorCode::OK) - LOG(ERROR) << "INS_BEGIN_OPERATION_CMD error while creating new operation handle: " << (int32_t) errorCode; + operType = OperationType::PUBLIC_OPERATION; + } + errorCode = handleBeginOperation(purpose, keyBlob, inParams, authToken, outParams, + operationHandle, operType); + if (errorCode == ErrorCode::OK && isOperationHandleExists(operationHandle)) { + LOG(DEBUG) << "Operation handle " << operationHandle << "already exists" + "in the opertion table. so aborting this opertaion."; + // abort the operation. + errorCode = abortOperation(operationHandle, operType); + if (errorCode == ErrorCode::OK) { + // retry begin to get an another operation handle. + errorCode = + handleBeginOperation(purpose, keyBlob, inParams, authToken, outParams, + operationHandle, operType); + if (errorCode == ErrorCode::OK && isOperationHandleExists(operationHandle)) { + errorCode = ErrorCode::UNKNOWN_ERROR; + LOG(ERROR) + << "INS_BEGIN_OPERATION_CMD: Failed in begin operation as the" + "operation handle already exists in the operation table." + << (int32_t)errorCode; + // abort the operation. + auto abortErr = abortOperation(operationHandle, operType); + if (abortErr != ErrorCode::OK) { + LOG(ERROR) << "Fail to abort the operation."; + errorCode = abortErr; + } } - _hidl_cb(errorCode, resultParams, generatedOpHandle); - return Void(); } } + // Create an entry inside the operation table for the new operation + // handle. + if (ErrorCode::OK == errorCode) + operationTable[operationHandle] = operType; + + _hidl_cb(errorCode, outParams, operationHandle); + return Void(); +} + +ErrorCode JavacardKeymaster4Device::handleBeginPublicKeyOperation( + KeyPurpose purpose, const hidl_vec& keyBlob, + const hidl_vec& inParams, hidl_vec& outParams, + uint64_t& operationHandle) { + BeginOperationRequest request; + request.purpose = legacy_enum_conversion(purpose); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + request.additional_params.Reinitialize(KmParamSet(inParams)); + + BeginOperationResponse response; + /* For Symmetric key operation, the BeginOperation returns + * KM_ERROR_INCOMPATIBLE_ALGORITHM error. */ + softKm_->BeginOperation(request, &response); + ErrorCode errorCode = legacy_enum_conversion(response.error); + LOG(DEBUG) << "INS_BEGIN_OPERATION_CMD softkm BeginOperation status: " + << (int32_t)errorCode; + if (ErrorCode::OK == errorCode) { + outParams = kmParamSet2Hidl(response.output_params); + operationHandle = response.op_handle; + } else { + LOG(ERROR) + << "INS_BEGIN_OPERATION_CMD error in softkm BeginOperation status: " + << (int32_t)errorCode; + } + return errorCode; +} +ErrorCode JavacardKeymaster4Device::handleBeginPrivateKeyOperation( + KeyPurpose purpose, const hidl_vec& keyBlob, + const hidl_vec& inParams, const HardwareAuthToken& authToken, + hidl_vec& outParams, uint64_t& operationHandle) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; cppbor::Array array; std::vector cborOutData; std::unique_ptr item; @@ -1089,78 +1101,107 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - // keyCharacteristics.hardwareEnforced is required to store algorithm, digest and padding values in operationInfo - // structure. To retrieve keyCharacteristics.hardwareEnforced, call getKeyCharacateristics. - // By calling getKeyCharacateristics also helps in finding a corrupted keyblob. + // keyCharacteristics.hardwareEnforced is required to store algorithm, digest + // and padding values in operationInfo structure. To retrieve + // keyCharacteristics.hardwareEnforced, call getKeyCharacateristics. By + // calling getKeyCharacateristics also helps in finding a corrupted keyblob. hidl_vec applicationId; hidl_vec applicationData; - if(getTag(inParams, Tag::APPLICATION_ID, param)) { + if (getTag(inParams, Tag::APPLICATION_ID, param)) { applicationId = param.blob; } - if(getTag(inParams, Tag::APPLICATION_DATA, param)) { + if (getTag(inParams, Tag::APPLICATION_DATA, param)) { applicationData = param.blob; } - //Call to getKeyCharacteristics. + // Call to getKeyCharacteristics. getKeyCharacteristics(keyBlob, applicationId, applicationData, - [&](ErrorCode error, KeyCharacteristics keyChars) { - errorCode = error; - keyCharacteristics = keyChars; - }); - LOG(DEBUG) << "INS_BEGIN_OPERATION_CMD getKeyCharacteristics status: " << (int32_t) errorCode; - - if(errorCode == ErrorCode::OK) { + [&](ErrorCode error, KeyCharacteristics keyChars) { + errorCode = error; + keyCharacteristics = keyChars; + }); + LOG(DEBUG) + << "INS_BEGIN_OPERATION_CMD StrongboxKM getKeyCharacteristics status: " + << (int32_t)errorCode; + + if (errorCode == ErrorCode::OK) { errorCode = ErrorCode::UNKNOWN_ERROR; - if(getTag(keyCharacteristics.hardwareEnforced, Tag::ALGORITHM, param)) { - errorCode = sendData(Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); - if(errorCode == ErrorCode::OK) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), + if (getTag(keyCharacteristics.hardwareEnforced, Tag::ALGORITHM, param)) { + errorCode = + sendData(Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + if (errorCode == ErrorCode::OK) { + // Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = decodeData( + cborConverter_, + std::vector(cborOutData.begin(), cborOutData.end() - 2), true, oprCtx_); if (item != nullptr) { - if(!cborConverter_.getKeyParameters(item, 1, outParams) || - !cborConverter_.getUint64(item, 2, operationHandle)) { + if (!cborConverter_.getKeyParameters(item, 1, outParams) || + !cborConverter_.getUint64(item, 2, operationHandle)) { errorCode = ErrorCode::UNKNOWN_ERROR; outParams.setToExternal(nullptr, 0); operationHandle = 0; - LOG(ERROR) << "INS_BEGIN_OPERATION_CMD: error in converting cbor data, status: " << (int32_t) errorCode; + LOG(ERROR) << "INS_BEGIN_OPERATION_CMD: error in converting cbor " + "data, status: " + << (int32_t)errorCode; } else { /* Store the operationInfo */ - oprCtx_->setOperationInfo(operationHandle, purpose, param.f.algorithm, inParams); + oprCtx_->setOperationInfo(operationHandle, purpose, + param.f.algorithm, inParams); } } } } else { - LOG(ERROR) << "INS_BEGIN_OPERATION_CMD couldn't find algorithm tag: " << (int32_t)Tag::ALGORITHM; + LOG(ERROR) << "INS_BEGIN_OPERATION_CMD couldn't find algorithm tag: " + << (int32_t)Tag::ALGORITHM; } } else { - LOG(ERROR) << "INS_BEGIN_OPERATION_CMD error in getKeyCharacteristics status: " << (int32_t) errorCode; + LOG(ERROR) + << "INS_BEGIN_OPERATION_CMD error in getKeyCharacteristics status: " + << (int32_t)errorCode; } - /* Create a new operation handle and add a entry inside the operation table map with - * key - new operation handle - * value - hal generated operation handle. - */ - if (ErrorCode::OK == errorCode) - errorCode = createOprHandleEntry(operationHandle, SB_KM_OPR, generatedOpHandle); + return errorCode; +} - _hidl_cb(errorCode, outParams, generatedOpHandle); - return Void(); +ErrorCode JavacardKeymaster4Device::handleBeginOperation( + KeyPurpose purpose, const hidl_vec& keyBlob, + const hidl_vec& inParams, const HardwareAuthToken& authToken, + hidl_vec& outParams, uint64_t& operationHandle, + OperationType& operType) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + if (operType == OperationType::PUBLIC_OPERATION) { + errorCode = handleBeginPublicKeyOperation(purpose, keyBlob, inParams, + outParams, operationHandle); + + // For Symmetric operations handleBeginPublicKeyOperation function + // returns INCOMPATIBLE_ALGORITHM error. Based on this error + // condition it fallbacks to private key operation. + if (errorCode == ErrorCode::INCOMPATIBLE_ALGORITHM) { + operType = OperationType::PRIVATE_OPERATION; + } + } + + if (operType == OperationType::PRIVATE_OPERATION) { + errorCode = handleBeginPrivateKeyOperation( + purpose, keyBlob, inParams, authToken, outParams, operationHandle); + } + return errorCode; } -Return JavacardKeymaster4Device::update(uint64_t halGeneratedOprHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { +Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; uint32_t inputConsumed = 0; hidl_vec outParams; hidl_vec output; - uint64_t operationHandle; UpdateOperationResponse response; - if (ErrorCode::OK != (errorCode = getOrigOperationHandle(halGeneratedOprHandle, operationHandle))) { + OperationType operType = getOperationType(operationHandle); + if (OperationType::UNKNOWN == operType) { // operation handle not found LOG(ERROR) << " Operation handle is invalid. This could happen if invalid operation handle is passed or if" << " secure element reset occurred."; - _hidl_cb(errorCode, inputConsumed, outParams, output); + _hidl_cb(ErrorCode::INVALID_OPERATION_HANDLE, inputConsumed, outParams, output); return Void(); } - if (!isStrongboxOperation(halGeneratedOprHandle)) { + if (OperationType::PUBLIC_OPERATION == operType) { /* SW keymaster (Public key operation) */ LOG(DEBUG) << "INS_UPDATE_OPERATION_CMD - swkm operation "; UpdateOperationRequest request; @@ -1249,34 +1290,34 @@ Return JavacardKeymaster4Device::update(uint64_t halGeneratedOprHandle, co LOG(DEBUG) << "Update operation status: " << (int32_t) errorCode; if(ErrorCode::OK != errorCode) { LOG(ERROR) << "Error in update operation, status: " << (int32_t) errorCode; - abort(halGeneratedOprHandle); + abort(operationHandle); } } if(ErrorCode::OK != errorCode) { /* Delete the entry from operation table. */ LOG(ERROR) << "Delete entry from operation table, status: " << (int32_t) errorCode; - deleteOprHandleEntry(halGeneratedOprHandle); + operationTable.erase(operationHandle); } _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); } -Return JavacardKeymaster4Device::finish(uint64_t halGeneratedOprHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { +Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - uint64_t operationHandle; hidl_vec outParams; hidl_vec output; FinishOperationResponse response; + OperationType operType = getOperationType(operationHandle); - if (ErrorCode::OK != (errorCode = getOrigOperationHandle(halGeneratedOprHandle, operationHandle))) { + if (OperationType::UNKNOWN == operType) { // operation handle not found LOG(ERROR) << " Operation handle is invalid. This could happen if invalid operation handle is passed or if" << " secure element reset occurred."; - _hidl_cb(errorCode, outParams, output); + _hidl_cb(ErrorCode::INVALID_OPERATION_HANDLE, outParams, output); return Void(); } - if (!isStrongboxOperation(halGeneratedOprHandle)) { + if (OperationType::PUBLIC_OPERATION == operType) { /* SW keymaster (Public key operation) */ LOG(DEBUG) << "FINISH - swkm operation "; FinishOperationRequest request; @@ -1386,54 +1427,83 @@ Return JavacardKeymaster4Device::finish(uint64_t halGeneratedOprHandle, co } if (ErrorCode::OK != errorCode) { LOG(ERROR) << "Error in finish operation, status: " << (int32_t) errorCode; - abort(halGeneratedOprHandle); + abort(operationHandle); } } /* Delete the entry from operation table. */ - deleteOprHandleEntry(halGeneratedOprHandle); + operationTable.erase(operationHandle); oprCtx_->clearOperationData(operationHandle); LOG(DEBUG) << "finish operation, status: " << (int32_t) errorCode; _hidl_cb(errorCode, outParams, output); return Void(); } -Return JavacardKeymaster4Device::abort(uint64_t halGeneratedOprHandle) { - ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - uint64_t operationHandle; - if (ErrorCode::OK != (errorCode = getOrigOperationHandle(halGeneratedOprHandle, operationHandle))) { - LOG(ERROR) << " Operation handle is invalid. This could happen if invalid operation handle is passed or if" - << " secure element reset occurred."; - return errorCode; - } - AbortOperationRequest request; - request.op_handle = operationHandle; +ErrorCode JavacardKeymaster4Device::abortPrivateKeyOperation( + uint64_t operationHandle) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; + + /* Convert input data to cbor format */ + array.add(operationHandle); + std::vector cborData = array.encode(); + + errorCode = + sendData(Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + + if (errorCode == ErrorCode::OK) { + // Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = decodeData( + cborConverter_, + std::vector(cborOutData.begin(), cborOutData.end() - 2), true, + oprCtx_); + } + return errorCode; +} - AbortOperationResponse response; - softKm_->AbortOperation(request, &response); +ErrorCode JavacardKeymaster4Device::abortPublicKeyOperation( + uint64_t operationHandle) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + AbortOperationRequest request; + request.op_handle = operationHandle; - errorCode = legacy_enum_conversion(response.error); - LOG(DEBUG) << "swkm abort operation, status: " << (int32_t) errorCode; - if (response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; - - /* Convert input data to cbor format */ - array.add(operationHandle); - std::vector cborData = array.encode(); - - errorCode = sendData(Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); - - if(errorCode == ErrorCode::OK) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), - true, oprCtx_); - } + AbortOperationResponse response; + softKm_->AbortOperation(request, &response); + + errorCode = legacy_enum_conversion(response.error); + return errorCode; +} + +ErrorCode JavacardKeymaster4Device::abortOperation(uint64_t operationHandle, + OperationType operType) { + if (operType == OperationType::UNKNOWN) + return ErrorCode::UNKNOWN_ERROR; + + if (OperationType::PUBLIC_OPERATION == operType) { + return abortPublicKeyOperation(operationHandle); + } else { + return abortPrivateKeyOperation(operationHandle); } - /* Delete the entry on this operationHandle */ - oprCtx_->clearOperationData(operationHandle); - deleteOprHandleEntry(halGeneratedOprHandle); - return errorCode; +} + +Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + OperationType operType = getOperationType(operationHandle); + if (OperationType::UNKNOWN == operType) { // operation handle not found + LOG(ERROR) << " Operation handle is invalid. This could happen if invalid " + "operation handle is passed or if" + << " secure element reset occurred."; + return ErrorCode::INVALID_OPERATION_HANDLE; + } + + errorCode = abortOperation(operationHandle, operType); + if (errorCode == ErrorCode::OK) { + /* Delete the entry on this operationHandle */ + oprCtx_->clearOperationData(operationHandle); + operationTable.erase(operationHandle); + } + return errorCode; } // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index c8ada383..ddb6b24a 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -54,6 +54,15 @@ using ::android::hardware::keymaster::V4_0::Tag; using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode; +enum class OperationType { + /* Public operations are processed inside softkeymaster */ + PUBLIC_OPERATION = 0, + /* Private operations are processed inside strongbox */ + PRIVATE_OPERATION = 1, + UNKNOWN = 2, +}; + + class JavacardKeymaster4Device : public IKeymasterDevice { public: @@ -87,8 +96,33 @@ class JavacardKeymaster4Device : public IKeymasterDevice { protected: CborConverter cborConverter_; - -private: + + private: + ErrorCode handleBeginPublicKeyOperation( + KeyPurpose purpose, const hidl_vec& keyBlob, + const hidl_vec& inParams, hidl_vec& outParams, + uint64_t& operationHandle); + + ErrorCode handleBeginPrivateKeyOperation( + KeyPurpose purpose, const hidl_vec& keyBlob, + const hidl_vec& inParams, + const HardwareAuthToken& authToken, hidl_vec& outParams, + uint64_t& operationHandle); + + ErrorCode handleBeginOperation(KeyPurpose purpose, + const hidl_vec& keyBlob, + const hidl_vec& inParams, + const HardwareAuthToken& authToken, + hidl_vec& outParams, + uint64_t& operationHandle, + OperationType& operType); + + ErrorCode abortOperation(uint64_t operationHandle, OperationType operType); + + ErrorCode abortPublicKeyOperation(uint64_t operationHandle); + + ErrorCode abortPrivateKeyOperation(uint64_t operationHandle); + std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; std::unique_ptr oprCtx_; bool isEachSystemPropertySet;