diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index 445f3737..f422bc26 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -94,6 +94,23 @@ enum class Instruction { INS_GET_CERT_CHAIN_CMD = INS_END_KM_PROVISION_CMD+22 }; +//Extended error codes +enum ExtendedErrors { + SW_CONDITIONS_NOT_SATISFIED = -10001, + UNSUPPORTED_CLA = -10002, + INVALID_P1P2 = -10003, + UNSUPPORTED_INSTRUCTION = -10004, + CMD_NOT_ALLOWED = -10005, + SW_WRONG_LENGTH = -10006, + INVALID_DATA = -10007, + CRYPTO_ILLEGAL_USE = -10008, + CRYPTO_ILLEGAL_VALUE = -10009, + CRYPTO_INVALID_INIT = -10010, + CRYPTO_NO_SUCH_ALGORITHM = -10011, + CRYPTO_UNINITIALIZED_KEY = -10012, + GENERIC_UNKNOWN_ERROR = -10013 +}; + static inline std::unique_ptr& getTransportFactoryInstance() { if(pTransportFactory == nullptr) { pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( @@ -123,6 +140,48 @@ static inline bool getTag(const hidl_vec& params, Tag tag, KeyPara return false; } +template +static T translateExtendedErrorsToHalErrors(T& errorCode) { + T err; + switch(static_cast(errorCode)) { + case SW_CONDITIONS_NOT_SATISFIED: + case UNSUPPORTED_CLA: + case INVALID_P1P2: + case INVALID_DATA: + case CRYPTO_ILLEGAL_USE: + case CRYPTO_ILLEGAL_VALUE: + case CRYPTO_INVALID_INIT: + case CRYPTO_UNINITIALIZED_KEY: + case GENERIC_UNKNOWN_ERROR: + err = T::UNKNOWN_ERROR; + break; + case CRYPTO_NO_SUCH_ALGORITHM: + err = T::UNSUPPORTED_ALGORITHM; + break; + case UNSUPPORTED_INSTRUCTION: + case CMD_NOT_ALLOWED: + case SW_WRONG_LENGTH: + err = T::UNIMPLEMENTED; + break; + default: + err = static_cast(errorCode); + break; + } + return err; +} + +template +static std::tuple, T> decodeData(CborConverter& cb, const std::vector& response, bool + hasErrorCode) { + std::unique_ptr item(nullptr); + T errorCode = T::OK; + std::tie(item, errorCode) = cb.decodeData(response, hasErrorCode); + + if (T::OK != errorCode) + errorCode = translateExtendedErrorsToHalErrors(errorCode); + return {std::move(item), errorCode}; +} + /* Generate new operation handle */ static ErrorCode generateOperationHandle(uint64_t& oprHandle) { std::map>::iterator it; @@ -390,7 +449,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa errorCode = sendData(Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if (ErrorCode::OK == errorCode) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborData.begin(), cborData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborData.begin(), cborData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters)) { @@ -441,7 +500,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { std::vector bstr; @@ -498,7 +557,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; @@ -530,7 +589,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getBinaryArray(item, 1, keyBlob) || @@ -576,7 +635,7 @@ Return JavacardKeymaster4Device::importKey(const hidl_vec& k if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getBinaryArray(item, 1, keyBlob) || @@ -631,7 +690,7 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getBinaryArray(item, 1, keyBlob) || @@ -664,7 +723,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics)) { @@ -730,7 +789,7 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA 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), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getMultiBinaryArray(item, 1, temp)) { @@ -741,7 +800,8 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA errorCode = sendData(Instruction::INS_GET_CERT_CHAIN_CMD, cborData, cborOutData, true); if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), + cborOutData.end()-2), true); if (item != nullptr) { std::vector chain; @@ -779,7 +839,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getBinaryArray(item, 1, upgradedKeyBlob)) @@ -802,7 +862,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; @@ -818,7 +878,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; @@ -834,7 +894,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; @@ -918,7 +978,7 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< 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) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { if(!cborConverter_.getKeyParameters(item, 1, outParams) || @@ -1007,7 +1067,7 @@ Return JavacardKeymaster4Device::update(uint64_t halGeneratedOprHandle, co if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { /*Ignore inputConsumed from javacard SE since HAL consumes all the input */ @@ -1065,10 +1125,10 @@ Return JavacardKeymaster4Device::finish(uint64_t halGeneratedOprHandle, co request.signature.Reinitialize(signature.data(), signature.size()); request.additional_params.Reinitialize(KmParamSet(inParams)); - //FinishOperationResponse response; softKm_->FinishOperation(request, &response); errorCode = legacy_enum_conversion(response.error); + if (response.error == KM_ERROR_OK) { outParams = kmParamSet2Hidl(response.output_params); output = kmBuffer2hidlVec(response.output); @@ -1135,7 +1195,7 @@ Return JavacardKeymaster4Device::finish(uint64_t halGeneratedOprHandle, co if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { //There is a change that this finish callback may gets called multiple times if the input data size @@ -1194,7 +1254,7 @@ Return JavacardKeymaster4Device::abort(uint64_t halGeneratedOprHandle if(errorCode == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + std::tie(item, errorCode) = decodeData(cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } } @@ -1226,8 +1286,8 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device if(ret == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData<::android::hardware::keymaster::V4_1::ErrorCode>(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); + std::tie(item, errorCode) = decodeData<::android::hardware::keymaster::V4_1::ErrorCode>( + cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; } @@ -1243,8 +1303,8 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device if(ret == ErrorCode::OK) { //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData<::android::hardware::keymaster::V4_1::ErrorCode>(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); + std::tie(item, errorCode) = decodeData<::android::hardware::keymaster::V4_1::ErrorCode>( + cborConverter_, std::vector(cborOutData.begin(), cborOutData.end()-2), true); } return errorCode; } diff --git a/HAL/keymaster/4.1/Provision.cpp b/HAL/keymaster/4.1/Provision.cpp index 34b6420d..e90cd7ef 100644 --- a/HAL/keymaster/4.1/Provision.cpp +++ b/HAL/keymaster/4.1/Provision.cpp @@ -49,7 +49,7 @@ enum class Instruction { INS_PROVISION_CERT_CHAIN_CMD = INS_BEGIN_KM_CMD+2, INS_PROVISION_CERT_PARAMS_CMD = INS_BEGIN_KM_CMD+3, INS_PROVISION_ATTEST_IDS_CMD = INS_BEGIN_KM_CMD+4, - INS_PROVISION_SHARED_SECRET_CMD = INS_BEGIN_KM_CMD+5, + INS_PROVISION_PRESHARED_SECRET_CMD = INS_BEGIN_KM_CMD+5, INS_SET_BOOT_PARAMS_CMD = INS_BEGIN_KM_CMD+6, INS_LOCK_PROVISIONING_CMD = INS_BEGIN_KM_CMD+7, INS_GET_PROVISION_STATUS_CMD = INS_BEGIN_KM_CMD+8, @@ -61,7 +61,7 @@ enum ProvisionStatus { PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x02, PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x04, PROVISION_STATUS_ATTEST_IDS = 0x08, - PROVISION_STATUS_SHARED_SECRET = 0x10, + PROVISION_STATUS_PRESHARED_SECRET = 0x10, PROVISION_STATUS_BOOT_PARAM = 0x20, PROVISION_STATUS_PROVISIONING_LOCKED = 0x40, }; @@ -406,7 +406,7 @@ static ErrorCode provisionAttestationIDs(std::unique_ptr& transport) { ErrorCode errorCode = ErrorCode::OK; cppbor::Array array; - Instruction ins = Instruction::INS_PROVISION_SHARED_SECRET_CMD; + Instruction ins = Instruction::INS_PROVISION_PRESHARED_SECRET_CMD; std::vector response; std::vector masterKey(kFakeKeyAgreementKey, kFakeKeyAgreementKey + sizeof(kFakeKeyAgreementKey)/sizeof(kFakeKeyAgreementKey[0])); @@ -484,7 +484,7 @@ static bool isSEProvisioned(uint64_t status) { if(status != (ProvisionStatus::PROVISION_STATUS_ATTESTATION_KEY | ProvisionStatus::PROVISION_STATUS_ATTESTATION_CERT_CHAIN | ProvisionStatus::PROVISION_STATUS_ATTESTATION_CERT_PARAMS | ProvisionStatus::PROVISION_STATUS_ATTEST_IDS | - ProvisionStatus::PROVISION_STATUS_SHARED_SECRET | ProvisionStatus::PROVISION_STATUS_BOOT_PARAM + ProvisionStatus::PROVISION_STATUS_PRESHARED_SECRET | ProvisionStatus::PROVISION_STATUS_BOOT_PARAM |ProvisionStatus::PROVISION_STATUS_PROVISIONING_LOCKED)) { ret = false; }