diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index 2e1c9b26..c0ec86ef 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -19,76 +19,117 @@ #include #include #include +#include #include using namespace cppbor; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::TagType; #define UNUSED(A) A = A -HardwareAuthenticatorType convertToHardwareAuthenticatorType(uint64_t val) { - switch (static_cast(val)) { - case HardwareAuthenticatorType::NONE: - return HardwareAuthenticatorType::NONE; - case HardwareAuthenticatorType::PASSWORD: - return HardwareAuthenticatorType::PASSWORD; - case HardwareAuthenticatorType::FINGERPRINT: - return HardwareAuthenticatorType::FINGERPRINT; - case HardwareAuthenticatorType::ANY: - return HardwareAuthenticatorType::ANY; - } +bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { + UNUSED(value); + UNUSED(keyParam); + UNUSED(tag); + return false; } -bool convertToTag(uint64_t val, Tag& tag) { - UNUSED(tag); - UNUSED(val); -#if 0 - switch (static_cast(val)) { - case TAG::ABC: - tag = TAG::ABC; - break; - case TAG::DEF: - tag = TAG::DEF; - break; - case TAG::GHI: - tag = TAG::GHI; - break; - default: - return false; +bool CborConverter::addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { + Map map; + for(size_t i = 0; i < keyParams.size(); i++) { + KeyParameter param = keyParams[i]; + TagType tagType = static_cast(param.tag & (0xF << 28)); + switch(tagType) { + case TagType::ENUM: + case TagType::ENUM_REP: + case TagType::UINT: + case TagType::UINT_REP: + map.add(static_cast(param.tag), param.f.integer); + break; + case TagType::ULONG: + case TagType::ULONG_REP: + map.add(static_cast(param.tag), param.f.longInteger); + break; + case TagType::DATE: + map.add(static_cast(param.tag), param.f.dateTime); + break; + case TagType::BOOL: + map.add(static_cast(param.tag), param.f.boolValue); + break; + case TagType::BIGNUM: + case TagType::BYTES: + map.add(static_cast(param.tag), (std::vector(param.blob))); + break; + default: + /* Invalid skip */ + break; + } } + array.add(std::move(map)); return true; -#endif - return false; } -bool getTagValue(Tag& tag, KeyParameter& keyParam, uint64_t& value) { - UNUSED(value); - UNUSED(keyParam); - UNUSED(tag); - return false; +bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, + ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) { + bool ret = false; + std::unique_ptr arrayItem(nullptr); + + getItemAtPos(item, pos, arrayItem); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + + if (!getKeyParameters(arrayItem, 0, keyCharacteristics.softwareEnforced)) { + return ret; + } + + if (!getKeyParameters(arrayItem, 1, keyCharacteristics.hardwareEnforced)) { + return ret; + } + //success + ret = true; + return ret; } bool CborConverter::getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam) { + const std::unique_ptr&> pair, KeyParameter& keyParam) { bool ret = false; uint64_t value; //TAG will be always uint32_t if (!getUint64(pair.first, 0, value)) { return ret; } - if (!convertToTag(value, keyParam.tag)) return false; + keyParam.tag = static_cast(value); if (MajorType::UINT == getType(pair.second)) { - if (!getUint64(pair.second, 0, value)) { - return ret; + TagType tagType = static_cast(keyParam.tag & (0xF << 28)); + switch(tagType) { + case TagType::ENUM: + case TagType::ENUM_REP: + case TagType::UINT: + case TagType::UINT_REP: + keyParam.f.integer = static_cast(value); + break; + case TagType::ULONG: + case TagType::ULONG_REP: + keyParam.f.longInteger = static_cast(value); + break; + case TagType::DATE: + keyParam.f.dateTime = static_cast(value); + break; + case TagType::BOOL: + keyParam.f.boolValue = static_cast(value); + break; + default: + /* Invalid skip */ + break; } - /* TODO*/ - //Convert value to corresponding enum and assign to keyParam.f } else if (MajorType::BSTR == getType(pair.second)) { - std::vector blob; + std::vector blob; if (!getBinaryArray(pair.second, 0, blob)) { return ret; } - keyParam.blob.setToExternal(blob.data(), blob.size()); + keyParam.blob.setToExternal(blob.data(), blob.size()); } return ret; } @@ -97,9 +138,31 @@ ParseResult CborConverter::decodeData(const std::vector cborData) { return parse(cborData); } +bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, + ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { + bool ret = false; + std::unique_ptr arrayItem(nullptr); + + getItemAtPos(item, pos, arrayItem); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + const Array* arr = arrayItem.get()->asArray(); + size_t arrSize = arr->size(); + for (int i = 0; i < arrSize; i++) { + std::vector innerData; + if (!getBinaryArray(arrayItem, i, innerData)) + return ret; + data[i].setToExternal(innerData.data(), innerData.size()); + } + ret = true; // success + return ret; +} + bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& value) { bool ret = false; - const std::unique_ptr& strItem = getItemAtPos(item, pos); + std::unique_ptr strItem(nullptr); + + getItemAtPos(item, pos, strItem); if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) return ret; @@ -115,19 +178,50 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params) { std::vector paramValue; bool ret = false; + std::unique_ptr arrayItem(nullptr); + + //1. Get ArrayItem + //2. First item in the array seed; second item in the array is nonce. + + getItemAtPos(item, pos, arrayItem); + if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + return ret; + //Seed - if (!getBinaryArray(item, pos, paramValue)) + if (!getBinaryArray(arrayItem, 0, paramValue)) return ret; params.seed.setToExternal(paramValue.data(), paramValue.size()); paramValue.clear(); + //nonce - if (!getBinaryArray(item, pos+1, paramValue)) + if (!getBinaryArray(arrayItem, 1, paramValue)) return ret; memcpy(params.nonce.data(), paramValue.data(), paramValue.size()); ret = true; return ret; } +bool CborConverter::addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& + verificationToken) { + array.add(verificationToken.challenge); + array.add(verificationToken.timestamp); + addKeyparameters(array, verificationToken.parametersVerified); + array.add(static_cast(verificationToken.securityLevel)); + array.add((std::vector(verificationToken.mac))); + return true; +} + +bool CborConverter::addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& + authToken) { + array.add(authToken.challenge); + array.add(authToken.userId); + array.add(authToken.authenticatorId); + array.add(static_cast(authToken.authenticatorType)); + array.add(authToken.timestamp); + array.add((std::vector(authToken.mac))); + return true; +} + bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& token) { bool ret = false; std::vector mac; @@ -144,34 +238,65 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr& item, cons uint64_t authType; if (!getUint64(item, pos+3, authType)) return ret; - token.authenticatorType = convertToHardwareAuthenticatorType(authType); + token.authenticatorType = static_cast(authType); //Timestamp if (!getUint64(item, pos+4, token.timestamp)) return ret; //MAC - if (!getBinaryArray(item, pos + 5, mac)) + if (!getBinaryArray(item, pos+5, mac)) + return ret; + token.mac.setToExternal(mac.data(), mac.size()); + ret = true; + return ret; +} + +bool CborConverter::getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& + token) { + bool ret = false; + std::vector mac; + //challenge + if (!getUint64(item, pos, token.challenge)) + return ret; + + //timestamp + if (!getUint64(item, pos+1, token.timestamp)) + return ret; + + //List of KeyParameters + if (!getKeyParameters(item, pos+2, token.parametersVerified)) + return ret; + + //AuthenticatorId + uint64_t val; + if (!getUint64(item, pos+3, val)) + return ret; + token.securityLevel = static_cast(val); + + //MAC + if (!getBinaryArray(item, pos+4, mac)) return ret; token.mac.setToExternal(mac.data(), mac.size()); ret = true; return ret; + } -bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams) { +bool CborConverter::getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) { bool ret = false; - const std::unique_ptr& mapItem = getItemAtPos(item, pos); + std::unique_ptr mapItem(nullptr); + getItemAtPos(item, pos, mapItem); if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) return ret; const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); for (int i = 0; i < mapSize; i++) { - KeyParameter param; + ::android::hardware::keymaster::V4_0::KeyParameter param; if (!getKeyparameter((*map)[i], param)) { return ret; } - keyParams.push_back(param); + keyParams[i] = std::move(param); } ret = true; return ret; } - diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index e8abdca3..0c28f055 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -15,212 +15,697 @@ ** limitations under the License. */ -#define LOG_TAG "android.hardware.keymaster@4.1-service.javacard" - -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -/* TODO Remove below UNUSED */ -#define UNUSED(a) a=a +//#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" +//#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" +#define APDU_CLS 0x80 +#define APDU_P1 0x40 +#define APDU_P2 0x00 +#define APDU_RESP_STATUS_OK 0x9000 -namespace android { -namespace hardware { namespace keymaster { namespace V4_1 { +namespace javacard { + + +enum class Instruction { + INS_GENERATE_KEY_CMD = 0x10, + INS_IMPORT_KEY_CMD = 0x11, + INS_IMPORT_WRAPPED_KEY_CMD = 0x12, + INS_EXPORT_KEY_CMD = 0x13, + INS_ATTEST_KEY_CMD = 0x14, + INS_UPGRADE_KEY_CMD = 0x15, + INS_DELETE_KEY_CMD = 0x16, + INS_DELETE_ALL_KEYS_CMD = 0x17, + INS_ADD_RNG_ENTROPY_CMD = 0x18, + INS_COMPUTE_SHARED_HMAC_CMD = 0x19, + INS_DESTROY_ATT_IDS_CMD = 0x1A, + INS_VERIFY_AUTHORIZATION_CMD = 0x1B, + INS_GET_HMAC_SHARING_PARAM_CMD = 0x1C, + INS_GET_KEY_CHARACTERISTICS_CMD = 0x1D, + INS_GET_HW_INFO_CMD = 0x1E, + INS_BEGIN_OPERATION_CMD = 0x1F, + INS_UPDATE_OPERATION_CMD = 0x20, + INS_FINISH_OPERATION_CMD = 0x21, + INS_ABORT_OPERATION_CMD = 0x22, + INS_PROVISION_CMD = 0x23, + INS_DEVICE_LOCKED_CMD = 0x24, + INS_EARLY_BOOT_ENDED_CMD = 0x25 +}; + +ErrorCode constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { + apduOut.push_back(static_cast(APDU_CLS)); //CLS + apduOut.push_back(static_cast(ins)); //INS + apduOut.push_back(static_cast(APDU_P1)); //P1 + apduOut.push_back(static_cast(APDU_P2)); //P2 + + if(UCHAR_MAX < inputData.size() && USHRT_MAX >= inputData.size()) { + //Extended length 3 bytes, starts with 0x00 + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(inputData.size() >> 8)); + apduOut.push_back(static_cast(inputData.size() & 0xFF)); + //Data + apduOut.insert(apduOut.end(), inputData.begin(), inputData.end()); + //Expected length of output + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(0x00)); + apduOut.push_back(static_cast(0x00));//Accepting complete length of output at a time + } else if(0 <= inputData.size() && UCHAR_MAX >= inputData.size()) { + //Short length + apduOut.push_back(static_cast(inputData.size())); + //Data + if(inputData.size() > 0) + apduOut.insert(apduOut.end(), inputData.begin(), inputData.end()); + //Expected length of output + apduOut.push_back(static_cast(0x00));//Accepting complete length of output at a time -JavacardKeymaster4Device::JavacardKeymaster4Device() { - // TODO + } else { + return (ErrorCode::INSUFFICIENT_BUFFER_SPACE); + } + + return (ErrorCode::OK);//success +} + +uint16_t getStatus(std::vector& inputData) { + //Last two bytes are the status SW0SW1 + return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); } -JavacardKeymaster4Device::~JavacardKeymaster4Device() { +inline ErrorCode sendData(std::unique_ptr& transport, Instruction ins, std::vector& inData, +std::vector& response) { + std::vector apdu; + ErrorCode ret = constructApduMessage(ins, inData, apdu); + if(ret != ErrorCode::OK) return ret; + + //if(!transport->openConnection()) { + // return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + //} + + if(!transport->sendData(apdu.data(), apdu.size(), response)) { + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + } + + if(APDU_RESP_STATUS_OK != getStatus(response)) { + return (ErrorCode::UNKNOWN_ERROR); + } + return (ErrorCode::OK);//success } // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { - _hidl_cb(::android::hardware::keymaster::V4_0::SecurityLevel::STRONGBOX, "JavacardKeymaster4.1Device v0.1", "Android Open Source Project"); + //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); + std::vector resp; + std::vector input; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + uint64_t securityLevel = static_cast(SecurityLevel::STRONGBOX); + hidl_string jcKeymasterName; + hidl_string jcKeymasterAuthor; + + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); + + if(ret == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(resp.begin(), resp.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector temp; + cborConverter_.getUint64(item, 0, securityLevel); //SecurityLevel + cborConverter_.getBinaryArray(item, 1, temp); + jcKeymasterName = std::string(temp.begin(), temp.end()); + temp.clear(); + cborConverter_.getBinaryArray(item, 2, temp); + jcKeymasterAuthor = std::string(temp.begin(), temp.end()); + } + } + _hidl_cb(static_cast(securityLevel), jcKeymasterName, jcKeymasterAuthor); return Void(); } Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); + std::vector cborData; + const uint8_t* pos; + std::vector input; + std::unique_ptr item; + std::string message; + HmacSharingParameters hmacSharingParameters; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + errorCode = sendData(pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborData.begin(), cborData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getHmacSharingParameters(item, 1, hmacSharingParameters); //HmacSharingParameters. + } + } + _hidl_cb(errorCode, hmacSharingParameters); return Void(); } -Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) { - // TODO implement - size_t size = params.size(); - UNUSED(size); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec& params, computeSharedHmac_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::vector cborOutData; + std::string message; + hidl_vec sharingCheck; + + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + std::vector tempVec; + cppbor::Array innerArray; + for(size_t i = 0; i < params.size(); ++i) { + innerArray.add(static_cast>(params[i].seed)); + for(size_t j = 0; i < params[j].nonce.size(); j++) { + tempVec.push_back(params[i].nonce[j]); + } + innerArray.add(tempVec); + tempVec.clear(); + } + array.add(std::move(innerArray)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Error Code + cborConverter_.getBinaryArray(item, 1, bstr); + sharingCheck.setToExternal(bstr.data(), bstr.size()); + } + } + _hidl_cb(errorCode, sharingCheck); return Void(); } -Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = parametersToVerify.size(); - UNUSED(size); - uint64_t challenge = authToken.challenge; - UNUSED(challenge); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHandle, const hidl_vec& parametersToVerify, const HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::vector cborOutData; + std::string message; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + VerificationToken verificationToken; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, parametersToVerify); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getVerificationToken(item, 1, verificationToken); + } + } + _hidl_cb(errorCode, verificationToken); return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { - // TODO implement - size_t size = data.size(); - UNUSED(size); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; +Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec& data) { + const uint8_t* pos; + cppbor::Array array; + std::vector cborOutData; + std::unique_ptr item; + std::string message; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(std::vector(data)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } -Return JavacardKeymaster4Device::generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) { - // TODO implement - UNUSED(_hidl_cb); - size_t size = keyParams.size(); - UNUSED(size); +Return JavacardKeymaster4Device::generateKey(const hidl_vec& keyParams, generateKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; + + cborConverter_.addKeyparameters(array, keyParams); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } -Return JavacardKeymaster4Device::importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { - // TODO implement - size_t size = keyParams.size(); - size = keyData.size(); - UNUSED(size); - UNUSED(keyFormat); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; + + cborConverter_.addKeyparameters(array, keyParams); + array.add(static_cast(keyFormat)); + array.add(std::vector(keyData)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + /* TODO keyBlob is BSTR */ + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } -Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { - // TODO implement - size_t size = wrappedKeyData.size(); - size = wrappingKeyBlob.size(); - size = maskingKey.size(); - size = unwrappingParams.size(); - UNUSED(size); - UNUSED(passwordSid); - UNUSED(biometricSid); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; + + array.add(std::vector(wrappedKeyData)); + array.add(std::vector(wrappingKeyBlob)); + array.add(std::vector(maskingKey)); + cborConverter_.addKeyparameters(array, unwrappingParams); + array.add(passwordSid); + array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO keyBlob is BSTR */ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyBlob.setToExternal(bstr.data(), bstr.size()); + cborConverter_.getKeyCharacteristics(item, 2, keyCharacteristics); + } + } + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); } Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) { - // TODO implement - size_t size = keyBlob.size(); - size = clientId.size(); - size = appData.size(); - UNUSED(size); - UNUSED(_hidl_cb); + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + KeyCharacteristics keyCharacteristics; + + array.add(std::vector(keyBlob)); + array.add(std::vector(clientId)); + array.add(std::vector(appData)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyCharacteristics(item, 1, keyCharacteristics); + } + } + _hidl_cb(errorCode, keyCharacteristics); return Void(); } -Return JavacardKeymaster4Device::exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { - // TODO implement - size_t size = clientId.size(); - size = keyBlob.size(); - size = appData.size(); - UNUSED(size); - UNUSED(keyFormat); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::exportKey(KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyMaterial; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + array.add(static_cast(keyFormat)); + array.add(std::vector(keyBlob)); + array.add(std::vector(clientId)); + array.add(std::vector(appData)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO Keyblobc - BSTR()*/ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + keyMaterial.setToExternal(bstr.data(), bstr.size()); + } + } + _hidl_cb(errorCode, keyMaterial); return Void(); } -Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) { - // TODO implement - size_t size = attestParams.size(); - size = keyToAttest.size(); - UNUSED(size); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec keyBlob; + std::vector cborOutData; + hidl_vec> certChain; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyToAttest)); + cborConverter_.addKeyparameters(array, attestParams); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getMultiBinaryArray(item, 1, certChain); + } + } + _hidl_cb(errorCode, certChain); return Void(); } -Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) { - // TODO implement - size_t size = keyBlobToUpgrade.size(); - size = upgradeParams.size(); - UNUSED(size); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec& upgradeParams, upgradeKey_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + hidl_vec upgradedKeyBlob; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyBlobToUpgrade)); + cborConverter_.addKeyparameters(array, upgradeParams); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + /* TODO Keyblob BSTR(ARRAY) */ + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getBinaryArray(item, 1, bstr); + upgradedKeyBlob.setToExternal(bstr.data(), bstr.size()); + } + } + _hidl_cb(errorCode, upgradedKeyBlob); return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { - // TODO implement - size_t size = keyBlob.size(); - UNUSED(size); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; +Return JavacardKeymaster4Device::deleteKey(const hidl_vec& keyBlob) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + array.add(std::vector(keyBlob)); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::deleteAllKeys() { - // TODO implement - return ::android::hardware::keymaster::V4_0::ErrorCode {}; +Return JavacardKeymaster4Device::deleteAllKeys() { + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + std::vector input; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + errorCode = sendData(pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::destroyAttestationIds() { - // TODO implement - return ::android::hardware::keymaster::V4_0::ErrorCode {}; +Return JavacardKeymaster4Device::destroyAttestationIds() { + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + std::vector input; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + errorCode = sendData(pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } -Return JavacardKeymaster4Device::begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) { - // TODO implement - UNUSED(purpose); - size_t size = keyBlob.size(); - size = inParams.size(); - UNUSED(size); - uint64_t challenge = authToken.challenge; - UNUSED(challenge); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec& inParams, const HardwareAuthToken& authToken, begin_cb _hidl_cb) { + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; + uint64_t operationHandle = 0; + + if (KeyPurpose::ENCRYPT == purpose || + KeyPurpose::VERIFY == purpose) { + /* Public key operations are handled here*/ + } else { + cppbor::Array array; + const uint8_t* pos; + std::vector cborOutData; + std::unique_ptr item; + std::string message; + + /* Convert input data to cbor format */ + array.add(static_cast(purpose)); + array.add(std::vector(keyBlob)); + cborConverter_.addKeyparameters(array, inParams); + cborConverter_.addHardwareAuthToken(array, authToken); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getUint64(item, 2, operationHandle); + } + } + } + _hidl_cb(errorCode, outParams, operationHandle); return Void(); } -Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = inParams.size(); - size = input.size(); - UNUSED(size); - uint64_t challange = verificationToken.challenge; - challange = authToken.challenge; - UNUSED(challange); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; + uint32_t inputConsumed = 0; + hidl_vec output; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getUint64(item, 1, inputConsumed); + cborConverter_.getKeyParameters(item, 2, outParams); + cborConverter_.getBinaryArray(item, 3, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } + } + _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); } -Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) { - // TODO implement - UNUSED(operationHandle); - size_t size = inParams.size(); - size = input.size(); - size = signature.size(); - uint64_t challange = authToken.challenge; - challange = verificationToken.challenge; - UNUSED(challange); - UNUSED(_hidl_cb); +Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + hidl_vec outParams; + hidl_vec output; + + /* Convert input data to cbor format */ + array.add(operationHandle); + cborConverter_.addKeyparameters(array, inParams); + array.add(std::vector(input)); + array.add(std::vector(signature)); + cborConverter_.addHardwareAuthToken(array, authToken); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_FINISH_OPERATION_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + std::vector bstr; + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + cborConverter_.getKeyParameters(item, 1, outParams); + cborConverter_.getBinaryArray(item, 2, bstr); + output.setToExternal(bstr.data(), bstr.size()); + } + } + _hidl_cb(errorCode, outParams, output); return Void(); } -Return<::android::hardware::keymaster::V4_0::ErrorCode> JavacardKeymaster4Device::abort(uint64_t operationHandle) { - // TODO implement - UNUSED(operationHandle); - return ::android::hardware::keymaster::V4_0::ErrorCode {}; +Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(operationHandle); + std::vector cborData = array.encode(); + + errorCode = sendData(pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + + if(errorCode == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. -Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) { - // TODO implement - UNUSED(passwordOnly); - size_t challenge = verificationToken.challenge; - UNUSED(challenge); - return ::android::hardware::keymaster::V4_1::ErrorCode {}; +Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) { + cppbor::Array array; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + + /* Convert input data to cbor format */ + array.add(passwordOnly); + cborConverter_.addVerificationToken(array, verificationToken); + std::vector cborData = array.encode(); + + /* TODO DeviceLocked command handled inside HAL */ + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + + if(ret == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device::earlyBootEnded() { - // TODO implement - return ::android::hardware::keymaster::V4_1::ErrorCode {}; + const uint8_t* pos; + std::unique_ptr item; + std::string message; + std::vector cborOutData; + std::vector cborInput; + ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + + ErrorCode ret = sendData(pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + + if(ret == ErrorCode::OK) { + std::tie(item, pos, message) = parse(std::vector(cborOutData.begin(), cborOutData.end()-2));//Skip last 2 bytes, it is status. + if (item != nullptr) { + cborConverter_.getErrorCode(item, 0, errorCode); //Errorcode + } + } + return errorCode; } +} // javacard } // namespace V4_1 } // namespace keymaster -} // namespace hardware -} // namespace android diff --git a/HAL/keymaster/4.1/OmapiTransport.cpp b/HAL/keymaster/4.1/OmapiTransport.cpp new file mode 100644 index 00000000..5aaefc91 --- /dev/null +++ b/HAL/keymaster/4.1/OmapiTransport.cpp @@ -0,0 +1,49 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include "Transport.h" + +#define PORT 8080 +#define IPADDR "10.9.40.24" +#define UNUSED_V(a) a=a + +namespace se_transport { + +bool OmapiTransport::openConnection() { + return true; +} + +bool OmapiTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { + std::vector test(inData, inData+inLen); + output = std::move(test); + return true; +} + +bool OmapiTransport::closeConnection() { + return true; +} + +bool OmapiTransport::isConnected() { + return true; +} + +} diff --git a/HAL/keymaster/4.1/SocketTransport.cpp b/HAL/keymaster/4.1/SocketTransport.cpp new file mode 100644 index 00000000..b03262d1 --- /dev/null +++ b/HAL/keymaster/4.1/SocketTransport.cpp @@ -0,0 +1,83 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +#include +#include +#include +#include +#include "Transport.h" + +/* TODO How to get these two values */ +#define PORT 8080 +#define IPADDR "10.9.40.24" +#define MAX_RECV_BUFFER_SIZE 2048 + +namespace se_transport { + +bool SocketTransport::openConnection() { + struct sockaddr_in serv_addr; + + if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + LOG(ERROR) << "Socket creation failed"; + return false; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + + // Convert IPv4 and IPv6 addresses from text to binary form + if(inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr)<=0) + { + LOG(ERROR) << "Invalid address/ Address not supported."; + return false; + } + + if (connect(mSocket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + LOG(ERROR) << "Connection failed."; + return false; + } + return true; +} + +bool SocketTransport::sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { + uint8_t buffer[MAX_RECV_BUFFER_SIZE]; + if (0 > send(mSocket, inData, inLen , 0 )) { + LOG(ERROR) << "Failed to send data over socket."; + return false; + } + ssize_t valRead = read( mSocket , buffer, MAX_RECV_BUFFER_SIZE); + if(0 > valRead) { + LOG(ERROR) << "Failed to read data from socket."; + } + for(size_t i = 0; i < valRead; i++) { + output.push_back(buffer[i]); + } + return true; +} + +bool SocketTransport::closeConnection() { + close(mSocket); + return true; +} + +bool SocketTransport::isConnected() { + //TODO + return true; +} + +} diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 9720ea6a..65302a74 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -13,15 +13,11 @@ // limitations under the License. // -cc_binary { - name: "android.hardware.keymaster@4.1-service.javacard", - relative_install_path: "hw", - vendor: true, - init_rc: ["4.1/android.hardware.keymaster@4.1-service.javacard.rc"], +cc_library { + name: "libJavacardKeymaster41", srcs: [ - "4.1/service.cpp", "4.1/JavacardKeymaster4Device.cpp", - "4.1/CborConverter.cpp" + "4.1/CborConverter.cpp", ], local_include_dirs: [ "include", @@ -35,7 +31,29 @@ cc_binary { "libhardware", "libhidlbase", "libkeymaster_messages", - "libcppbor_external", + "libcppbor_external", + "omapi_external", "android.hardware.keymaster@4.1", + "android.hardware.keymaster@4.0", + "libjc_transport", + ], +} + +cc_library { + name: "libjc_transport", + host_supported: true, + vendor_available: true, + + srcs: [ + "4.1/SocketTransport.cpp", + "4.1/OmapiTransport.cpp" + ], + export_include_dirs: [ + "include" + ], + shared_libs: [ + "libbinder", + "libbase", + "liblog", ], } diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index eae9f4e3..5cd60584 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define EMPTY(A) *(A*)nullptr @@ -47,47 +48,76 @@ using ::android::hardware::keymaster::V4_0::VerificationToken; class CborConverter { -public: - CborConverter() = default; - ~CborConverter() = default; - - ParseResult decodeData(const std::vector cborData); - - /* Use this function to get both signed and usinged integers.*/ - template - bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); - bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); - bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); - bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); - bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, std::vector keyParams); - - -private: - inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } - bool getKeyparameter(const std::pair&, - const std::unique_ptr&> pair, KeyParameter& keyParam); - inline const std::unique_ptr& getItemAtPos(const std::unique_ptr& item, const uint32_t pos) { - const Array* arr = nullptr; - - if (MajorType::ARRAY != getType(item)) { - return EMPTY(std::unique_ptr); - } - arr = item.get()->asArray(); - if (arr->size() < (pos + 1)) { - return EMPTY(std::unique_ptr); + public: + CborConverter() = default; + ~CborConverter() = default; + + ParseResult decodeData(const std::vector cborData); + + /* Use this function to get both signed and usinged integers.*/ + template + bool getUint64(const std::unique_ptr& item, const uint32_t pos, T& value); + bool getHmacSharingParameters(const std::unique_ptr& item, const uint32_t pos, HmacSharingParameters& params); + bool getBinaryArray(const std::unique_ptr& item, const uint32_t pos, std::vector& vec); + bool getHardwareAuthToken(const std::unique_ptr& item, const uint32_t pos, HardwareAuthToken& authType); + bool getKeyParameters(const std::unique_ptr& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams); + bool addKeyparameters(Array& array, const android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& + keyParams); + bool addHardwareAuthToken(Array& array, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& + authToken); + bool getVerificationToken(const std::unique_ptr& item, const uint32_t pos, VerificationToken& + token); + bool getKeyCharacteristics(const std::unique_ptr &item, const uint32_t pos, + ::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics); + bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, + ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data); + bool addVerificationToken(Array& array, const ::android::hardware::keymaster::V4_0::VerificationToken& + verificationToken); + + template) || + (std::is_same_v)>> + inline bool getErrorCode(const std::unique_ptr& item, const uint32_t pos, T& errorCode) { + bool ret = false; + uint64_t errorVal; + if (!getUint64(item, pos, errorVal)) { + return ret; + } + errorCode = static_cast(errorVal); + + ret = true; + return ret; + } + + + + + private: + inline MajorType getType(const std::unique_ptr &item) { return item.get()->type(); } + bool getKeyparameter(const std::pair&, + const std::unique_ptr&> pair, KeyParameter& keyParam); + inline void getItemAtPos(const std::unique_ptr& item, const uint32_t pos, std::unique_ptr& subItem) { + Array* arr = nullptr; + + if (MajorType::ARRAY != getType(item)) { + return; + } + arr = const_cast(item.get()->asArray()); + if (arr->size() < (pos + 1)) { + return; + } + subItem = std::move((*arr)[pos]); } - return (*arr)[pos]; - } }; template bool CborConverter::getUint64(const std::unique_ptr& item, const uint32_t pos, T& value) { bool ret = false; - const std::unique_ptr& intItem = getItemAtPos(item, pos); - + std::unique_ptr intItem(nullptr); + getItemAtPos(item, pos, intItem); + if ((intItem == nullptr) || - (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || - ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { + (std::is_unsigned::value && (MajorType::UINT != getType(intItem))) || + ((std::is_signed::value && (MajorType::NINT != getType(intItem))))) { return ret; } diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index f8e54856..6bb62387 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -15,63 +15,84 @@ ** limitations under the License. */ -#ifndef ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ -#define ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ +#ifndef KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ +#define KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ +#include #include #include #include +#include #include "CborConverter.h" +#include "TransportFactory.h" -namespace android { -namespace hardware { namespace keymaster { namespace V4_1 { +namespace javacard { -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::sp; + +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; +using ::android::hardware::keymaster::V4_0::HardwareAuthToken; +using ::android::hardware::keymaster::V4_0::HmacSharingParameters; +using ::android::hardware::keymaster::V4_0::KeyCharacteristics; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::OperationHandle; +using ::android::hardware::keymaster::V4_0::SecurityLevel; +using ::android::hardware::keymaster::V4_0::VerificationToken; +using ::android::hardware::keymaster::V4_1::IKeymasterDevice; +using ::android::hardware::keymaster::V4_1::Tag; + +using V41ErrorCode = ::android::hardware::keymaster::V4_1::ErrorCode; class JavacardKeymaster4Device : public IKeymasterDevice { public: - explicit JavacardKeymaster4Device(); - virtual ~JavacardKeymaster4Device(); + JavacardKeymaster4Device() { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + assert(pTransportFactory->openConnection() && "Failed to open connection with secure element"); + } + + virtual ~JavacardKeymaster4Device() {} + // Methods from ::android::hardware::keymaster::V4_0::IKeymasterDevice follow. Return getHardwareInfo(getHardwareInfo_cb _hidl_cb) override; Return getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override; - Return computeSharedHmac(const hidl_vec<::android::hardware::keymaster::V4_0::HmacSharingParameters>& params, computeSharedHmac_cb _hidl_cb) override; - Return verifyAuthorization(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& parametersToVerify, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> addRngEntropy(const hidl_vec& data) override; - Return generateKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, generateKey_cb _hidl_cb) override; - Return importKey(const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams, ::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) override; - Return importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) override; + Return computeSharedHmac(const hidl_vec& params, computeSharedHmac_cb _hidl_cb) override; + Return verifyAuthorization(uint64_t operationHandle, const hidl_vec& parametersToVerify, const HardwareAuthToken& authToken, verifyAuthorization_cb _hidl_cb) override; + Return addRngEntropy(const hidl_vec& data) override; + Return generateKey(const hidl_vec& keyParams, generateKey_cb _hidl_cb) override; + Return importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) override; + Return importWrappedKey(const hidl_vec& wrappedKeyData, const hidl_vec& wrappingKeyBlob, const hidl_vec& maskingKey, const hidl_vec& unwrappingParams, uint64_t passwordSid, uint64_t biometricSid, importWrappedKey_cb _hidl_cb) override; Return getKeyCharacteristics(const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb _hidl_cb) override; - Return exportKey(::android::hardware::keymaster::V4_0::KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) override; - Return attestKey(const hidl_vec& keyToAttest, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& attestParams, attestKey_cb _hidl_cb) override; - Return upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& upgradeParams, upgradeKey_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteKey(const hidl_vec& keyBlob) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> deleteAllKeys() override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> destroyAttestationIds() override; - Return begin(::android::hardware::keymaster::V4_0::KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, begin_cb _hidl_cb) override; - Return update(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, update_cb _hidl_cb) override; - Return finish(uint64_t operationHandle, const hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& inParams, const hidl_vec& input, const hidl_vec& signature, const ::android::hardware::keymaster::V4_0::HardwareAuthToken& authToken, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken, finish_cb _hidl_cb) override; - Return<::android::hardware::keymaster::V4_0::ErrorCode> abort(uint64_t operationHandle) override; + Return exportKey(KeyFormat keyFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb _hidl_cb) override; + Return attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) override; + Return upgradeKey(const hidl_vec& keyBlobToUpgrade, const hidl_vec& upgradeParams, upgradeKey_cb _hidl_cb) override; + Return deleteKey(const hidl_vec& keyBlob) override; + Return deleteAllKeys() override; + Return destroyAttestationIds() override; + Return begin(KeyPurpose purpose, const hidl_vec& keyBlob, const hidl_vec& inParams, const HardwareAuthToken& authToken, begin_cb _hidl_cb) override; + Return update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, update_cb _hidl_cb) override; + Return finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, const HardwareAuthToken& authToken, const VerificationToken& verificationToken, finish_cb _hidl_cb) override; + Return abort(uint64_t operationHandle) override; // Methods from ::android::hardware::keymaster::V4_1::IKeymasterDevice follow. - Return<::android::hardware::keymaster::V4_1::ErrorCode> deviceLocked(bool passwordOnly, const ::android::hardware::keymaster::V4_0::VerificationToken& verificationToken) override; - Return<::android::hardware::keymaster::V4_1::ErrorCode> earlyBootEnded() override; + Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; + Return earlyBootEnded() override; protected: CborConverter cborConverter_; + std::unique_ptr pTransportFactory; }; +} // namespace javacard } // namespace V4_1 } // namespace keymaster -} // namespace hardware -} // namespace android -#endif // ANDROID_HARDWARE_KEYMASTER_V4_1_JAVACARDKEYMASTER4DEVICE_H_ +#endif // KEYMASTER_V4_1_JAVACARD_JAVACARDKEYMASTER4DEVICE_H_ diff --git a/HAL/keymaster/include/Transport.h b/HAL/keymaster/include/Transport.h new file mode 100644 index 00000000..aadb3f00 --- /dev/null +++ b/HAL/keymaster/include/Transport.h @@ -0,0 +1,56 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +#ifndef __SE_TRANSPORT__ +#define __SE_TRANSPORT__ + +namespace se_transport { + +class ITransport { + public: + virtual ~ITransport(){} + virtual bool openConnection() = 0; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) = 0; + virtual bool closeConnection() = 0; + virtual bool isConnected() = 0; + +}; + +class OmapiTransport : public ITransport { + +public: + + bool openConnection() override; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + bool closeConnection() override; + bool isConnected() override; + +}; + +class SocketTransport : public ITransport { + +public: + bool openConnection() override; + virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; + bool closeConnection() override; + bool isConnected() override; +private: + int mSocket; + +}; + +} +#endif /* __SE_TRANSPORT__ */ diff --git a/HAL/keymaster/include/TransportFactory.h b/HAL/keymaster/include/TransportFactory.h new file mode 100644 index 00000000..2e01e66b --- /dev/null +++ b/HAL/keymaster/include/TransportFactory.h @@ -0,0 +1,56 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +#ifndef __SE_TRANSPORT_FACTORY__ +#define __SE_TRANSPORT_FACTORY__ + +#include "Transport.h" + +namespace se_transport { + +class TransportFactory { + public: + TransportFactory(bool isEmulator) { + if (!isEmulator) + mTransport = std::unique_ptr(new OmapiTransport()); + else + mTransport = std::unique_ptr(new SocketTransport()); + } + + ~TransportFactory() {} + + inline bool openConnection() { + return mTransport->openConnection(); + } + + inline bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { + return mTransport->sendData(inData, inLen, output); + } + + inline bool closeConnection() { + return mTransport->closeConnection(); + } + + inline bool isConnected() { + return mTransport->isConnected(); + } + + private: + std::unique_ptr mTransport; + +}; +} +#endif /* __SE_TRANSPORT_FACTORY__ */