diff --git a/HAL/keymaster/4.1/CborConverter.cpp b/HAL/keymaster/4.1/CborConverter.cpp index e7217c2d..1d22b6e8 100644 --- a/HAL/keymaster/4.1/CborConverter.cpp +++ b/HAL/keymaster/4.1/CborConverter.cpp @@ -77,7 +77,7 @@ bool CborConverter::getKeyCharacteristics(const std::unique_ptr &item, con bool ret = false; std::unique_ptr arrayItem(nullptr); getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; if (!getKeyParameters(arrayItem, 0, keyCharacteristics.softwareEnforced)) { @@ -209,9 +209,9 @@ bool CborConverter::getKeyParameter(const std::pair& { KeyParameter keyParam; keyParam.tag = static_cast(key); - if(!getBinaryArray(pair.second, 0, keyParam.blob)) { - return ret; - } + const Bstr* bstr = pair.second.get()->asBstr(); + if(bstr == nullptr) return ret; + keyParam.blob = bstr->value(); keyParams.push_back(std::move(keyParam)); return true; } @@ -223,19 +223,22 @@ bool CborConverter::getKeyParameter(const std::pair& return ret; } + bool CborConverter::getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, - ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data) { + std::vector>& data) { bool ret = false; std::unique_ptr arrayItem(nullptr); getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; const Array* arr = arrayItem.get()->asArray(); size_t arrSize = arr->size(); for (int i = 0; i < arrSize; i++) { - if (!getBinaryArray(arrayItem, i, data[i])) + std::vector temp; + if (!getBinaryArray(arrayItem, i, temp)) return ret; + data.push_back(std::move(temp)); } ret = true; // success return ret; @@ -246,7 +249,7 @@ ::android::hardware::hidl_vec& value) { bool ret = false; std::unique_ptr strItem(nullptr); getItemAtPos(item, pos, strItem); - if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + if ((strItem == nullptr) || (MajorType::BSTR != getType(strItem))) return ret; const Bstr* bstr = strItem.get()->asBstr(); @@ -260,7 +263,7 @@ bool CborConverter::getBinaryArray(const std::unique_ptr& item, const uint bool ret = false; std::unique_ptr strItem(nullptr); getItemAtPos(item, pos, strItem); - if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem))) + if ((strItem == nullptr) || (MajorType::BSTR != getType(strItem))) return ret; const Bstr* bstr = strItem.get()->asBstr(); @@ -280,7 +283,7 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, //2. First item in the array seed; second item in the array is nonce. getItemAtPos(item, pos, arrayItem); - if ((arrayItem == nullptr) && (MajorType::ARRAY != getType(arrayItem))) + if ((arrayItem == nullptr) || (MajorType::ARRAY != getType(arrayItem))) return ret; //Seed @@ -296,13 +299,10 @@ bool CborConverter::getHmacSharingParameters(const std::unique_ptr& item, } bool CborConverter::addVerificationToken(Array& array, const VerificationToken& - verificationToken) { - std::vector encodedParamsVerified; + verificationToken, std::vector& encodedParamsVerified) { Array vToken; vToken.add(verificationToken.challenge); vToken.add(verificationToken.timestamp); - //addKeyparameters(vToken, verificationToken.parametersVerified); - /* TODO Need to get proper encodedParamsVerified */ vToken.add(std::move(encodedParamsVerified)); vToken.add(static_cast(verificationToken.securityLevel)); vToken.add((std::vector(verificationToken.mac))); @@ -383,7 +383,7 @@ bool CborConverter::getKeyParameters(const std::unique_ptr& item, const ui std::unique_ptr mapItem(nullptr); std::vector params; getItemAtPos(item, pos, mapItem); - if ((mapItem == nullptr) && (MajorType::MAP != getType(mapItem))) + if ((mapItem == nullptr) || (MajorType::MAP != getType(mapItem))) return ret; const Map* map = mapItem.get()->asMap(); size_t mapSize = map->size(); diff --git a/HAL/keymaster/4.1/CommonUtils.cpp b/HAL/keymaster/4.1/CommonUtils.cpp new file mode 100644 index 00000000..67993957 --- /dev/null +++ b/HAL/keymaster/4.1/CommonUtils.cpp @@ -0,0 +1,228 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace keymaster { +namespace V4_1 { +namespace javacard { + +hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set) { + hidl_vec result; + if (set.length == 0 || set.params == nullptr) + return result; + + result.resize(set.length); + keymaster_key_param_t* params = set.params; + for (size_t i = 0; i < set.length; ++i) { + auto tag = params[i].tag; + result[i].tag = legacy_enum_conversion(tag); + switch (typeFromTag(tag)) { + case KM_ENUM: + case KM_ENUM_REP: + result[i].f.integer = params[i].enumerated; + break; + case KM_UINT: + case KM_UINT_REP: + result[i].f.integer = params[i].integer; + break; + case KM_ULONG: + case KM_ULONG_REP: + result[i].f.longInteger = params[i].long_integer; + break; + case KM_DATE: + result[i].f.dateTime = params[i].date_time; + break; + case KM_BOOL: + result[i].f.boolValue = params[i].boolean; + break; + case KM_BIGNUM: + case KM_BYTES: + result[i].blob.setToExternal(const_cast(params[i].blob.data), + params[i].blob.data_length); + break; + case KM_INVALID: + default: + params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + return result; +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { + keymaster_key_param_set_t set; + + set.params = new keymaster_key_param_t[keyParams.size()]; + set.length = keyParams.size(); + + for (size_t i = 0; i < keyParams.size(); ++i) { + auto tag = legacy_enum_conversion(keyParams[i].tag); + switch (typeFromTag(tag)) { + case KM_ENUM: + case KM_ENUM_REP: + set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + set.params[i] = keymaster_param_bool(tag); + else + set.params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + set.params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: + set.params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + + return set; +} + +ErrorCode getEcCurve(const EC_GROUP *group, EcCurve& ecCurve) { + int curve = EC_GROUP_get_curve_name(group); + switch(curve) { + case NID_secp224r1: + ecCurve = EcCurve::P_224; + break; + case NID_X9_62_prime256v1: + ecCurve = EcCurve::P_256; + break; + case NID_secp384r1: + ecCurve = EcCurve::P_384; + break; + case NID_secp521r1: + ecCurve = EcCurve::P_521; + break; + default: + return ErrorCode::UNSUPPORTED_EC_CURVE; + } + return ErrorCode::OK; +} + +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& +publicKey, EcCurve& ecCurve) { + ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; + EVP_PKEY *pkey = nullptr; + const uint8_t *data = pkcs8Blob.data(); + + d2i_PrivateKey(EVP_PKEY_EC, &pkey, &data, pkcs8Blob.size()); + if(!pkey) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + + UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey)); + if(!ec_key.get()) + return legacy_enum_conversion(TranslateLastOpenSslError()); + + //Get EC Group + const EC_GROUP *group = EC_KEY_get0_group(ec_key.get()); + if(group == NULL) + return errorCode; + + if(ErrorCode::OK != (errorCode = getEcCurve(group, ecCurve))) { + return errorCode; + } + + //Extract private key. + const BIGNUM *privBn = EC_KEY_get0_private_key(ec_key.get()); + int privKeyLen = BN_num_bytes(privBn); + std::unique_ptr privKey(new uint8_t[privKeyLen]); + BN_bn2bin(privBn, privKey.get()); + secret.insert(secret.begin(), privKey.get(), privKey.get()+privKeyLen); + + //Extract public key. + const EC_POINT *point = EC_KEY_get0_public_key(ec_key.get()); + int pubKeyLen=0; + pubKeyLen = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + std::unique_ptr pubKey(new uint8_t[pubKeyLen]); + EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, pubKey.get(), pubKeyLen, NULL); + publicKey.insert(publicKey.begin(), pubKey.get(), pubKey.get()+pubKeyLen); + + EVP_PKEY_free(pkey); + return ErrorCode::OK; +} + +ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& +pubModulus) { + ErrorCode errorCode = ErrorCode::INVALID_KEY_BLOB; + const BIGNUM *n=NULL, *e=NULL, *d=NULL; + EVP_PKEY *pkey = nullptr; + const uint8_t *data = pkcs8Blob.data(); + + d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &data, pkcs8Blob.size()); + if(!pkey) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + + UniquePtr rsa_key(EVP_PKEY_get1_RSA(pkey)); + if(!rsa_key.get()) { + return legacy_enum_conversion(TranslateLastOpenSslError()); + } + + RSA_get0_key(rsa_key.get(), &n, &e, &d); + if(d != NULL && n != NULL) { + /*private exponent */ + int privExpLen = BN_num_bytes(d); + std::unique_ptr privExp(new uint8_t[privExpLen]); + BN_bn2bin(d, privExp.get()); + /* public modulus */ + int pubModLen = BN_num_bytes(n); + std::unique_ptr pubMod(new uint8_t[pubModLen]); + BN_bn2bin(n, pubMod.get()); + + privateExp.insert(privateExp.begin(), privExp.get(), privExp.get()+privExpLen); + pubModulus.insert(pubModulus.begin(), pubMod.get(), pubMod.get()+pubModLen); + } else { + return errorCode; + } + EVP_PKEY_free(pkey); + return ErrorCode::OK; +} + + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index ef1e4f04..7e04681a 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -15,35 +15,43 @@ ** limitations under the License. */ -#include #include #include #include #include #include -#include -#include #include #include #include +#include +#include #include #include #include +#include +#include -//#define JAVACARD_KEYMASTER_NAME "JavacardKeymaster4.1Device v0.1" -//#define JAVACARD_KEYMASTER_AUTHOR "Android Open Source Project" #define APDU_CLS 0x80 #define APDU_P1 0x40 #define APDU_P2 0x00 #define APDU_RESP_STATUS_OK 0x9000 +#define ROOT_RSA_KEY "/data/data/rsa_key.der" +#define ROOT_RSA_CERT "/data/data/certificate_rsa.der" +/*This property is used to check if javacard is already provisioned or not */ +#define KM_JAVACARD_PROVISIONED_PROPERTY "keymaster.javacard.provisioned" namespace keymaster { namespace V4_1 { namespace javacard { +static std::unique_ptr pTransportFactory = nullptr; constexpr size_t kOperationTableSize = 16; +struct KM_AUTH_LIST_Delete { + void operator()(KM_AUTH_LIST* p) { KM_AUTH_LIST_free(p); } +}; + enum class Instruction { INS_GENERATE_KEY_CMD = 0x10, INS_IMPORT_KEY_CMD = 0x11, @@ -70,145 +78,84 @@ enum class Instruction { INS_EARLY_BOOT_ENDED_CMD = 0x26, }; -inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { - return static_cast(value); -} - -inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { - return static_cast(value); -} - -inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { - return static_cast(value); -} - -inline keymaster_tag_t legacy_enum_conversion(const Tag value) { - return keymaster_tag_t(value); +static inline std::unique_ptr& getTransportFactoryInstance() { + if(pTransportFactory == nullptr) { + pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( + android::base::GetBoolProperty("ro.kernel.qemu", false))); + pTransportFactory->openConnection(); + } + return pTransportFactory; } -inline Tag legacy_enum_conversion(const keymaster_tag_t value) { - return Tag(value); -} +ErrorCode encodeParametersVerified(const VerificationToken& verificationToken, std::vector asn1ParamsVerified) { + if (verificationToken.parametersVerified.size() > 0) { + AuthorizationSet paramSet; + KeymasterBlob derBlob; + UniquePtr kmAuthList(KM_AUTH_LIST_new()); -inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { - return keymaster_tag_get_type(tag); -} + paramSet.Reinitialize(KmParamSet(verificationToken.parametersVerified)); -keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { - keymaster_key_param_set_t set; - - set.params = new keymaster_key_param_t[keyParams.size()]; - set.length = keyParams.size(); - - for (size_t i = 0; i < keyParams.size(); ++i) { - auto tag = legacy_enum_conversion(keyParams[i].tag); - switch (typeFromTag(tag)) { - case KM_ENUM: - case KM_ENUM_REP: - set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); - break; - case KM_UINT: - case KM_UINT_REP: - set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); - break; - case KM_ULONG: - case KM_ULONG_REP: - set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); - break; - case KM_DATE: - set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); - break; - case KM_BOOL: - if (keyParams[i].f.boolValue) - set.params[i] = keymaster_param_bool(tag); - else - set.params[i].tag = KM_TAG_INVALID; - break; - case KM_BIGNUM: - case KM_BYTES: - set.params[i] = - keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); - break; - case KM_INVALID: - default: - set.params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; + auto err = build_auth_list(paramSet, kmAuthList.get()); + if (err != KM_ERROR_OK) { + return legacy_enum_conversion(err); + } + int len = i2d_KM_AUTH_LIST(kmAuthList.get(), nullptr); + if (len < 0) { + return legacy_enum_conversion(TranslateLastOpenSslError()); } - } - - return set; -} -class KmParamSet : public keymaster_key_param_set_t { - public: - explicit KmParamSet(const hidl_vec& keyParams) - : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} - KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { - other.length = 0; - other.params = nullptr; + if (!derBlob.Reset(len)) { + return legacy_enum_conversion(KM_ERROR_MEMORY_ALLOCATION_FAILED); } - KmParamSet(const KmParamSet&) = delete; - ~KmParamSet() { delete[] params; } -}; -static inline hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set) { - hidl_vec result; - if (set.length == 0 || set.params == nullptr) - return result; - - result.resize(set.length); - keymaster_key_param_t* params = set.params; - for (size_t i = 0; i < set.length; ++i) { - auto tag = params[i].tag; - result[i].tag = legacy_enum_conversion(tag); - switch (typeFromTag(tag)) { - case KM_ENUM: - case KM_ENUM_REP: - result[i].f.integer = params[i].enumerated; - break; - case KM_UINT: - case KM_UINT_REP: - result[i].f.integer = params[i].integer; - break; - case KM_ULONG: - case KM_ULONG_REP: - result[i].f.longInteger = params[i].long_integer; - break; - case KM_DATE: - result[i].f.dateTime = params[i].date_time; - break; - case KM_BOOL: - result[i].f.boolValue = params[i].boolean; - break; - case KM_BIGNUM: - case KM_BYTES: - result[i].blob.setToExternal(const_cast(params[i].blob.data), - params[i].blob.data_length); - break; - case KM_INVALID: - default: - params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; + uint8_t* p = derBlob.writable_data(); + len = i2d_KM_AUTH_LIST(kmAuthList.get(), &p); + if (len < 0) { + return legacy_enum_conversion(TranslateLastOpenSslError()); } + asn1ParamsVerified.insert(asn1ParamsVerified.begin(), p, p+len); + derBlob.release(); } - return result; -} - -inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { - hidl_vec result; - result.setToExternal(const_cast(buf.peek_read()), buf.available_read()); - return result; + return ErrorCode::OK; } -static inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { - for(int i = 0; i < size; ++i) { - to.push_back(from[i]); +ErrorCode prepareCborArrayFromRawKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& blob, cppbor::Array& + array) { + ErrorCode errorCode = ErrorCode::OK; + AuthorizationSet paramSet; + keymaster_algorithm_t algorithm; + if(keyFormat == KeyFormat::PKCS8) { + + paramSet.Reinitialize(KmParamSet(keyParams)); + paramSet.GetTagValue(TAG_ALGORITHM, &algorithm); + + if(KM_ALGORITHM_RSA == algorithm) { + std::vector privExp; + std::vector modulus; + if(ErrorCode::OK != (errorCode = rsaRawKeyFromPKCS8(std::vector(blob), privExp, modulus))) { + return errorCode; + } + array.add(privExp); + array.add(modulus); + } else if(KM_ALGORITHM_EC == algorithm) { + std::vector privKey; + std::vector pubKey; + EcCurve curve; + if(ErrorCode::OK != (errorCode = ecRawKeyFromPKCS8(std::vector(blob), privKey, pubKey, curve))) { + return errorCode; + } + array.add(privKey); + array.add(pubKey); + } else { + return ErrorCode::UNSUPPORTED_ALGORITHM; + } + } else if(keyFormat == KeyFormat::RAW) { + array.add(std::vector(blob)); } + return errorCode; } -static inline ErrorCode parseWrappedKey(const hidl_vec& wrappedKeyData, std::vector& iv, std::vector& transitKey, +ErrorCode parseWrappedKey(const hidl_vec& wrappedKeyData, std::vector& iv, std::vector& transitKey, std::vector& secureKey, std::vector& tag, hidl_vec& authList, KeyFormat& keyFormat, std::vector& wrappedKeyDescription) { KeymasterBlob kmIv; @@ -218,11 +165,12 @@ keyFormat, std::vector& wrappedKeyDescription) { AuthorizationSet authSet; keymaster_key_format_t kmKeyFormat; KeymasterBlob kmWrappedKeyDescription; - KeymasterKeyBlob kmWrappedKeyData; - kmWrappedKeyData.key_material = dup_buffer(wrappedKeyData.data(), wrappedKeyData.size()); + size_t keyDataLen = wrappedKeyData.size(); + uint8_t *keyData = dup_buffer(wrappedKeyData.data(), keyDataLen); + keymaster_key_blob_t keyMaterial = {keyData, keyDataLen}; - keymaster_error_t error = parse_wrapped_key(kmWrappedKeyData, &kmIv, &kmTransitKey, + keymaster_error_t error = parse_wrapped_key(KeymasterKeyBlob(keyMaterial), &kmIv, &kmTransitKey, &kmSecureKey, &kmTag, &authSet, &kmKeyFormat, &kmWrappedKeyDescription); if (error != KM_ERROR_OK) return legacy_enum_conversion(error); @@ -237,21 +185,6 @@ keyFormat, std::vector& wrappedKeyDescription) { return ErrorCode::OK; } - -JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( - []() -> auto { - auto context = new JavaCardSoftKeymasterContext(); - context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); - return context; - }(), - kOperationTableSize)), oprCtx_(new OperationContext()), setUpBootParams(false) { - pTransportFactory = std::unique_ptr(new se_transport::TransportFactory( - android::base::GetBoolProperty("ro.kernel.qemu", false))); - pTransportFactory->openConnection(); -} - -JavacardKeymaster4Device::~JavacardKeymaster4Device() {} - ErrorCode constructApduMessage(Instruction& ins, std::vector& inputData, std::vector& apduOut) { apduOut.push_back(static_cast(APDU_CLS)); //CLS apduOut.push_back(static_cast(ins)); //INS @@ -290,64 +223,187 @@ uint16_t getStatus(std::vector& inputData) { return (inputData.at(inputData.size()-2) << 8) | (inputData.at(inputData.size()-1)); } -/* This method should be called at the time when HAL is initialized for the first time */ -Return setBootParams(std::unique_ptr& transport) { - cppbor::Array array; - std::vector apdu; - std::vector response; - Instruction ins = Instruction::INS_SET_BOOT_PARAMS_CMD; +bool readDataFromFile(const char *filename, std::vector& data) { + FILE *fp; + bool ret = true; + fp = fopen(filename, "rb"); + if(fp == NULL) { + LOG(ERROR) << "Failed to open file: " << filename; + return false; + } + fseek(fp, 0L, SEEK_END); + long int filesize = ftell(fp); + rewind(fp); + std::unique_ptr buf(new uint8_t[filesize]); + if( 0 == fread(buf.get(), filesize, 1, fp)) { + LOG(ERROR) << "No Content in the file: " << filename; + ret = false; + } + if(true == ret) { + data.insert(data.begin(), buf.get(), buf.get() + filesize); + } + fclose(fp); + return ret; +} + +ErrorCode initiateProvision() { + /* This is just a reference implemenation */ + std::string brand("Google"); + std::string device("Pixel 3A"); + std::string product("Pixel"); + std::string serial("UGYJFDjFeRuBEH"); + std::string imei("987080543071019"); + std::string meid("27863510227963"); + std::string manufacturer("Foxconn"); + std::string model("HD1121"); + AuthorizationSet authSet(AuthorizationSetBuilder() + .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA) + .Authorization(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN) + .Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256) + .Authorization(TAG_KEY_SIZE, 2048) + .Authorization(TAG_PURPOSE, static_cast(0x7F)) /* The value 0x7F is not present in types.hal */ + .Authorization(TAG_ATTESTATION_ID_BRAND, brand.data(), brand.size()) + .Authorization(TAG_ATTESTATION_ID_DEVICE, device.data(), device.size()) + .Authorization(TAG_ATTESTATION_ID_PRODUCT, product.data(), product.size()) + .Authorization(TAG_ATTESTATION_ID_SERIAL, serial.data(), serial.size()) + .Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size()) + .Authorization(TAG_ATTESTATION_ID_MEID, meid.data(), meid.size()) + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, manufacturer.data(), manufacturer.size()) + .Authorization(TAG_ATTESTATION_ID_MODEL, model.data(), model.size())); + + hidl_vec keyParams = kmParamSet2Hidl(authSet); + std::vector data; + if(!readDataFromFile(ROOT_RSA_KEY, data)) { + LOG(ERROR) << " Failed to read the Root rsa key"; + return ErrorCode::UNKNOWN_ERROR; + } + return JavacardKeymaster4Device::provision(keyParams, KeyFormat::PKCS8, data); +} + +Return setBootParams() { std::vector verifiedBootKey(32, 0); std::vector verifiedBootKeyHash(32, 0); - array.add(GetOsVersion()). - add(GetOsPatchlevel()). - /* Verified Boot Key */ - add(verifiedBootKey). - /* Verified Boot Hash */ - add(verifiedBootKeyHash). - /* boot state */ - add(static_cast(KM_VERIFIED_BOOT_UNVERIFIED)). - /* device locked */ - add(0); /* false */ - std::vector cborData = array.encode(); - ErrorCode ret = constructApduMessage(ins, cborData, apdu); + return JavacardKeymaster4Device::setBootParams(GetOsVersion(), GetOsPatchlevel(), verifiedBootKey, verifiedBootKeyHash, + KM_VERIFIED_BOOT_UNVERIFIED, 0/*deviceLocked*/); +} + +ErrorCode sendData(Instruction ins, std::vector& inData, std::vector& response) { + ErrorCode ret = ErrorCode::UNKNOWN_ERROR; + std::vector apdu; + + if(!android::base::GetBoolProperty(KM_JAVACARD_PROVISIONED_PROPERTY, false)) { + if(ErrorCode::OK != (ret = setBootParams())) { + LOG(ERROR) << "Failed to set boot params"; + return ret; + } + + if(ErrorCode::OK != (ret = initiateProvision())) { + LOG(ERROR) << "Failed to provision the device"; + return ret; + } + android::base::SetProperty(KM_JAVACARD_PROVISIONED_PROPERTY, "true"); + } + + ret = constructApduMessage(ins, inData, apdu); if(ret != ErrorCode::OK) return ret; - if(!transport->sendData(apdu.data(), apdu.size(), response)) { + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { return (ErrorCode::UNKNOWN_ERROR); } - return ErrorCode::OK; + return (ErrorCode::OK);//success } -ErrorCode sendData(JavacardKeymaster4Device *pKeymaster, std::unique_ptr& transport, Instruction ins, std::vector& inData, -std::vector& response) { - ErrorCode ret = ErrorCode::UNKNOWN_ERROR; +ErrorCode JavacardKeymaster4Device::provision(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& +keyData) { + cppbor::Array array; + cppbor::Array subArray; + std::unique_ptr item; std::vector apdu; + hidl_vec keyBlob; + ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + Instruction ins = Instruction::INS_PROVISION_CMD; + std::vector response; + CborConverter cborConverter; - if(!pKeymaster->getBootParamsInitialized()) { - if((ret = setBootParams(transport)) != ErrorCode::OK) { - return ret; - } - pKeymaster->setBootParams(true); + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyFormat, keyData, subArray))) { + return errorCode; } + /* construct cbor */ + cborConverter.addKeyparameters(array, keyParams); + array.add(static_cast(keyFormat)); + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); + std::vector cborData = array.encode(); - ret = constructApduMessage(ins, inData, apdu); + if(ErrorCode::OK != (errorCode = constructApduMessage(ins, cborData, apdu))) + return errorCode; + + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { + return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); + } + + if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { + return (ErrorCode::UNKNOWN_ERROR); + } + + if((response.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter.decodeData(std::vector(response.begin(), response.end()-2), + true); + } + return errorCode; +} + +ErrorCode JavacardKeymaster4Device::setBootParams(uint32_t osVersion, uint32_t osPatchLevel, const std::vector& verifiedBootKey, +std::vector& verifiedBootKeyHash, keymaster_verified_boot_t kmVerifiedBoot, bool deviceLocked) { + cppbor::Array array; + std::vector apdu; + std::vector response; + Instruction ins = Instruction::INS_SET_BOOT_PARAMS_CMD; + array.add(osVersion). + add(osPatchLevel). + /* Verified Boot Key */ + add(verifiedBootKey). + /* Verified Boot Hash */ + add(verifiedBootKeyHash). + /* boot state */ + add(static_cast(kmVerifiedBoot)). + /* device locked */ + add(static_cast(deviceLocked)); + std::vector cborData = array.encode(); + + ErrorCode ret = constructApduMessage(ins, cborData, apdu); if(ret != ErrorCode::OK) return ret; - if(!transport->sendData(apdu.data(), apdu.size(), response)) { + if(!getTransportFactoryInstance()->sendData(apdu.data(), apdu.size(), response)) { return (ErrorCode::SECURE_HW_COMMUNICATION_FAILED); } if((response.size() < 2) || (getStatus(response) != APDU_RESP_STATUS_OK)) { return (ErrorCode::UNKNOWN_ERROR); } - return (ErrorCode::OK);//success + return ErrorCode::OK; + +} + +JavacardKeymaster4Device::JavacardKeymaster4Device(): softKm_(new ::keymaster::AndroidKeymaster( + []() -> auto { + auto context = new JavaCardSoftKeymasterContext(); + context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel()); + return context; + }(), + kOperationTableSize)), oprCtx_(new OperationContext()) { + } +JavacardKeymaster4Device::~JavacardKeymaster4Device() {} + // Methods from IKeymasterDevice follow. Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_cb) { //_hidl_cb(SecurityLevel::STRONGBOX, JAVACARD_KEYMASTER_NAME, JAVACARD_KEYMASTER_AUTHOR); @@ -358,7 +414,7 @@ Return JavacardKeymaster4Device::getHardwareInfo(getHardwareInfo_cb _hidl_ hidl_string jcKeymasterName; hidl_string jcKeymasterAuthor; - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_GET_HW_INFO_CMD, input, resp); + ErrorCode ret = sendData(Instruction::INS_GET_HW_INFO_CMD, input, resp); if((ret == ErrorCode::OK) && (resp.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -385,7 +441,7 @@ Return JavacardKeymaster4Device::getHmacSharingParameters(getHmacSharingPa HmacSharingParameters hmacSharingParameters; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); + errorCode = sendData(Instruction::INS_GET_HMAC_SHARING_PARAM_CMD, input, cborData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -419,7 +475,7 @@ Return JavacardKeymaster4Device::computeSharedHmac(const hidl_vec cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_COMPUTE_SHARED_HMAC_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -448,7 +504,7 @@ Return JavacardKeymaster4Device::verifyAuthorization(uint64_t operationHan cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_VERIFY_AUTHORIZATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -472,7 +528,7 @@ Return JavacardKeymaster4Device::addRngEntropy(const hidl_vec(data)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_ADD_RNG_ENTROPY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -494,7 +550,7 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& cborConverter_.addKeyparameters(array, keyParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_GENERATE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -510,55 +566,31 @@ Return JavacardKeymaster4Device::generateKey(const hidl_vec& } Return JavacardKeymaster4Device::importKey(const hidl_vec& keyParams, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb _hidl_cb) { - keymaster_error_t error = KM_ERROR_UNKNOWN_ERROR; - hidl_vec inKey; - KeymasterKeyBlob key_material; - - if (keyFormat == KeyFormat::PKCS8) { - ImportKeyRequest request; - request.key_description.Reinitialize(KmParamSet(keyParams)); - request.key_format = legacy_enum_conversion(keyFormat); - request.SetKeyMaterial(keyData.data(), keyData.size()); - - ImportKeyResponse response; - softKm_->ImportKey(request, &response); - - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - error = response.error; - if (response.error == KM_ERROR_OK) { - key_material = KeymasterKeyBlob(response.key_blob); - inKey.setToExternal(const_cast(key_material.key_material), key_material.key_material_size); - } - if(error != KM_ERROR_OK) { - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - _hidl_cb(legacy_enum_conversion(error), resultKeyBlob, resultCharacteristics); - return Void(); - } - } else if (keyFormat == KeyFormat::RAW) { - //convert keyData to keyMaterial - inKey = keyData; - } else { - KeyCharacteristics resultCharacteristics; - hidl_vec resultKeyBlob; - _hidl_cb(legacy_enum_conversion(KM_ERROR_UNSUPPORTED_KEY_FORMAT), resultKeyBlob, resultCharacteristics); - return Void(); - } - cppbor::Array array; std::unique_ptr item; hidl_vec keyBlob; std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; KeyCharacteristics keyCharacteristics; + cppbor::Array subArray; + if(keyFormat != KeyFormat::PKCS8 && keyFormat != KeyFormat::RAW) { + _hidl_cb(ErrorCode::UNSUPPORTED_KEY_FORMAT, keyBlob, keyCharacteristics); + return Void(); + } cborConverter_.addKeyparameters(array, keyParams); - array.add(static_cast(KeyFormat::RAW)); //PKCS8 is already converted to RAW - array.add(std::vector(inKey)); + array.add(static_cast(KeyFormat::RAW)); //javacard accepts only RAW. + if(ErrorCode::OK != (errorCode = prepareCborArrayFromRawKey(keyParams, keyFormat, keyData, subArray))) { + _hidl_cb(errorCode, keyBlob, keyCharacteristics); + return Void(); + } + std::vector encodedArray = subArray.encode(); + cppbor::Bstr bstr(encodedArray.begin(), encodedArray.end()); + array.add(bstr); + std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_IMPORT_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -593,20 +625,21 @@ Return JavacardKeymaster4Device::importWrappedKey(const hidl_vec& _hidl_cb(errorCode, keyBlob, keyCharacteristics); return Void(); } - array.add(transitKey); - array.add(iv); - array.add(static_cast(keyFormat)); cborConverter_.addKeyparameters(array, authList); + array.add(static_cast(keyFormat)); array.add(secureKey); array.add(tag); + array.add(iv); + array.add(transitKey); array.add(std::vector(wrappingKeyBlob)); array.add(std::vector(maskingKey)); cborConverter_.addKeyparameters(array, unwrappingParams); + array.add(std::vector(wrappedKeyDescription)); array.add(passwordSid); array.add(biometricSid); /* TODO if biometricSid optional if user not sent this don't encode this cbor format */ std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_IMPORT_WRAPPED_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -634,7 +667,7 @@ Return JavacardKeymaster4Device::getKeyCharacteristics(const hidl_vec(appData)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -653,7 +686,6 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const h ExportKeyRequest request; request.key_format = legacy_enum_conversion(exportFormat); request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); - //addClientAndAppData(clientId, appData, &request.additional_params); ExportKeyResponse response; softKm_->ExportKey(request, &response); @@ -664,31 +696,6 @@ Return JavacardKeymaster4Device::exportKey(KeyFormat exportFormat, const h } _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob); return Void(); -/* - cppbor::Array array; - std::unique_ptr item; - hidl_vec keyMaterial; - std::vector cborOutData; - ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - - array.add(static_cast(exportFormat)); - array.add(std::vector(keyBlob)); - array.add(std::vector(clientId)); - array.add(std::vector(appData)); - std::vector cborData = array.encode(); - - errorCode = sendData(this, pTransportFactory, Instruction::INS_EXPORT_KEY_CMD, cborData, cborOutData); - - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); - if (item != nullptr) { - cborConverter_.getBinaryArray(item, 1, keyMaterial); - } - } - _hidl_cb(errorCode, keyMaterial); - return Void();*/ } Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb _hidl_cb) { @@ -703,14 +710,25 @@ Return JavacardKeymaster4Device::attestKey(const hidl_vec& keyToA cborConverter_.addKeyparameters(array, attestParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_ATTEST_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + std::vector> temp; + std::vector rootCert; //Skip last 2 bytes in cborData, it contains status. std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), true); if (item != nullptr) { - cborConverter_.getMultiBinaryArray(item, 1, certChain); + cborConverter_.getMultiBinaryArray(item, 1, temp); + } + if(readDataFromFile(ROOT_RSA_CERT, rootCert)) { + temp.push_back(std::move(rootCert)); + certChain.resize(temp.size()); + for(int i = 0; i < temp.size(); i++) { + certChain[i] = temp[i]; + } + } else { + LOG(ERROR) << "No root certificate found"; } } _hidl_cb(errorCode, certChain); @@ -728,7 +746,7 @@ Return JavacardKeymaster4Device::upgradeKey(const hidl_vec& keyBl cborConverter_.addKeyparameters(array, upgradeParams); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_UPGRADE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -751,7 +769,7 @@ Return JavacardKeymaster4Device::deleteKey(const hidl_vec& k array.add(std::vector(keyBlob)); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_DELETE_KEY_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -767,7 +785,7 @@ Return JavacardKeymaster4Device::deleteAllKeys() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); + errorCode = sendData(Instruction::INS_DELETE_ALL_KEYS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -783,7 +801,7 @@ Return JavacardKeymaster4Device::destroyAttestationIds() { std::vector input; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; - errorCode = sendData(this, pTransportFactory, Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); + errorCode = sendData(Instruction::INS_DESTROY_ATT_IDS_CMD, input, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -797,6 +815,12 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; hidl_vec outParams; uint64_t operationHandle = 0; + hidl_vec resultParams; + + if(keyBlob.size() == 0) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, resultParams, operationHandle); + return Void(); + } if (KeyPurpose::ENCRYPT == purpose || KeyPurpose::VERIFY == purpose) { BeginOperationRequest request; @@ -807,7 +831,6 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< BeginOperationResponse response; softKm_->BeginOperation(request, &response); - hidl_vec resultParams; if (response.error == KM_ERROR_OK) { resultParams = kmParamSet2Hidl(response.output_params); } @@ -820,6 +843,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cppbor::Array array; std::vector cborOutData; std::unique_ptr item; + std::unique_ptr blobItem = nullptr; + KeyCharacteristics keyCharacteristics; /* Convert input data to cbor format */ array.add(static_cast(purpose)); @@ -828,7 +853,17 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); + /* keyCharacteristics.hardwareEnforced is required to store algorithm, digest and padding values in operationInfo + * structure. To retrieve keyCharacteristics.hardwareEnforced, parse the keyBlob. + */ + /* TODO if keyBlob is corrupted it crashes in cbor */ + std::tie(blobItem, errorCode) = cborConverter_.decodeData(std::vector(keyBlob), false); + + if(blobItem == nullptr) { + _hidl_cb(errorCode, outParams, operationHandle); + return Void(); + } + errorCode = sendData(Instruction::INS_BEGIN_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -838,7 +873,8 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.getKeyParameters(item, 1, outParams); cborConverter_.getUint64(item, 2, operationHandle); /* Store the operationInfo */ - oprCtx_->setOperationInfo(operationHandle, purpose, inParams); + cborConverter_.getKeyCharacteristics(blobItem, 3, keyCharacteristics); + oprCtx_->setOperationInfo(operationHandle, purpose, keyCharacteristics.hardwareEnforced); } } _hidl_cb(errorCode, outParams, operationHandle); @@ -872,16 +908,21 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi cppbor::Array array; std::unique_ptr item; std::vector cborOutData; + std::vector asn1ParamsVerified; + + if(ErrorCode::OK != (errorCode = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } // Convert input data to cbor format array.add(operationHandle); cborConverter_.addKeyparameters(array, inParams); array.add(data); cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); + errorCode = sendData(Instruction::INS_UPDATE_OPERATION_CMD, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -905,8 +946,7 @@ Return JavacardKeymaster4Device::update(uint64_t operationHandle, const hi } } if(ErrorCode::OK != errorCode) { - /* Delete the entry on this operationHandle */ - oprCtx_->clearOperationData(operationHandle); + abort(operationHandle); } _hidl_cb(errorCode, inputConsumed, outParams, output); return Void(); @@ -944,6 +984,11 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi std::unique_ptr item; std::vector cborOutData; int keyParamPos, outputPos; + std::vector asn1ParamsVerified; + + if(ErrorCode::OK != (errorCode = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } // Convert input data to cbor format array.add(operationHandle); @@ -960,10 +1005,10 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi outputPos = 3; } cborConverter_.addHardwareAuthToken(array, authToken); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); - errorCode = sendData(this, pTransportFactory, ins, cborData, cborOutData); + errorCode = sendData(ins, cborData, cborOutData); if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -982,28 +1027,36 @@ Return JavacardKeymaster4Device::finish(uint64_t operationHandle, const hi output = tempOut; } } - /* Delete the entry on this operationHandle */ - oprCtx_->clearOperationData(operationHandle); + abort(operationHandle); _hidl_cb(errorCode, outParams, output); return Void(); } Return JavacardKeymaster4Device::abort(uint64_t operationHandle) { - cppbor::Array array; - std::unique_ptr item; - std::vector cborOutData; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; + AbortOperationRequest request; + request.op_handle = operationHandle; - /* Convert input data to cbor format */ - array.add(operationHandle); - std::vector cborData = array.encode(); + AbortOperationResponse response; + softKm_->AbortOperation(request, &response); - errorCode = sendData(this, pTransportFactory, Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + errorCode = legacy_enum_conversion(response.error); + if (response.error == KM_ERROR_INVALID_OPERATION_HANDLE) { + cppbor::Array array; + std::unique_ptr item; + std::vector cborOutData; - if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { - //Skip last 2 bytes in cborData, it contains status. - std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), - true); + /* Convert input data to cbor format */ + array.add(operationHandle); + std::vector cborData = array.encode(); + + errorCode = sendData(Instruction::INS_ABORT_OPERATION_CMD, cborData, cborOutData); + + if((errorCode == ErrorCode::OK) && (cborOutData.size() > 2)) { + //Skip last 2 bytes in cborData, it contains status. + std::tie(item, errorCode) = cborConverter_.decodeData(std::vector(cborOutData.begin(), cborOutData.end()-2), + true); + } } /* Delete the entry on this operationHandle */ oprCtx_->clearOperationData(operationHandle); @@ -1016,14 +1069,20 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::unique_ptr item; std::vector cborOutData; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; + std::vector asn1ParamsVerified; + ErrorCode ret = ErrorCode::UNKNOWN_ERROR; + + if(ErrorCode::OK != (ret = encodeParametersVerified(verificationToken, asn1ParamsVerified))) { + return errorCode; + } /* Convert input data to cbor format */ array.add(passwordOnly); - cborConverter_.addVerificationToken(array, verificationToken); + cborConverter_.addVerificationToken(array, verificationToken, asn1ParamsVerified); std::vector cborData = array.encode(); /* TODO DeviceLocked command handled inside HAL */ - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); + ret = sendData(Instruction::INS_DEVICE_LOCKED_CMD, cborData, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. @@ -1040,7 +1099,7 @@ Return<::android::hardware::keymaster::V4_1::ErrorCode> JavacardKeymaster4Device std::vector cborInput; ::android::hardware::keymaster::V4_1::ErrorCode errorCode = ::android::hardware::keymaster::V4_1::ErrorCode::UNKNOWN_ERROR; - ErrorCode ret = sendData(this, pTransportFactory, Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); + ErrorCode ret = sendData(Instruction::INS_EARLY_BOOT_ENDED_CMD, cborInput, cborOutData); if((ret == ErrorCode::OK) && (cborOutData.size() > 2)) { //Skip last 2 bytes in cborData, it contains status. diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index b37b4a18..7e242162 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -189,20 +189,20 @@ ErrorCode OperationContext::finish(uint64_t operHandle, const std::vector newInput(first, end); if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, newInput.data(), newInput.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } if(extraData > 0) { std::vector finalInput(input.cend()-extraData, input.cend()); if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, finalInput.data(), finalInput.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } } else { if(ErrorCode::OK != (errorCode = handleInternalUpdate(operHandle, input.data(), input.size(), - Operation::Finish, cb))) { + Operation::Update, cb))) { return errorCode; } } @@ -221,7 +221,7 @@ ErrorCode OperationContext::internalUpdate(uint64_t operHandle, uint8_t* input, int inputConsumed=0; bool dataSendToSE = true; int blockSize = 0; - BufferedData data = operationTable[operHandle].data; + BufferedData& data = operationTable[operHandle].data; int bufIndex = data.buf_len; if(Algorithm::AES == operationTable[operHandle].info.alg) { diff --git a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp index 76731d5d..1186b398 100644 --- a/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp +++ b/HAL/keymaster/4.1/java_card_soft_keymaster_context.cpp @@ -14,45 +14,23 @@ * limitations under the License. */ -#include - -#include - -#include #include -#include -#include -#include -#include #include +#include #include - -#include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include #include +#include +#include #include -#include -#include -#include -#include -#include - -#include +#include #include -#include -#include - +#include using std::unique_ptr; +using ::keymaster::V4_1::javacard::KmParamSet; namespace keymaster { @@ -61,105 +39,6 @@ JavaCardSoftKeymasterContext::JavaCardSoftKeymasterContext(keymaster_security_le JavaCardSoftKeymasterContext::~JavaCardSoftKeymasterContext() {} -keymaster_error_t JavaCardSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description, - const keymaster_key_origin_t origin, - const KeymasterKeyBlob& key_material, - KeymasterKeyBlob* blob, - AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const { - if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) { - return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE; - } - - keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_, - os_patchlevel_, hw_enforced, sw_enforced); - if (error != KM_ERROR_OK) return error; - - AuthorizationSet hidden; - error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust); - if (error != KM_ERROR_OK) return error; - - size_t size = key_material.SerializedSize(); - - if (!blob->Reset(size)) - return KM_ERROR_MEMORY_ALLOCATION_FAILED; - - uint8_t* p = blob->writable_data(); - p = key_material.Serialize(p, blob->end()); - - return KM_ERROR_OK; -} - -inline keymaster_tag_t legacy_enum_conversion(const Tag value) { - return keymaster_tag_t(value); -} - -inline Tag legacy_enum_conversion(const keymaster_tag_t value) { - return Tag(value); -} - -inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { - return keymaster_tag_get_type(tag); -} - -keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams) { - keymaster_key_param_set_t set; - - set.params = new keymaster_key_param_t[keyParams.size()]; - set.length = keyParams.size(); - - for (size_t i = 0; i < keyParams.size(); ++i) { - auto tag = legacy_enum_conversion(keyParams[i].tag); - switch (typeFromTag(tag)) { - case KM_ENUM: - case KM_ENUM_REP: - set.params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); - break; - case KM_UINT: - case KM_UINT_REP: - set.params[i] = keymaster_param_int(tag, keyParams[i].f.integer); - break; - case KM_ULONG: - case KM_ULONG_REP: - set.params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); - break; - case KM_DATE: - set.params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); - break; - case KM_BOOL: - if (keyParams[i].f.boolValue) - set.params[i] = keymaster_param_bool(tag); - else - set.params[i].tag = KM_TAG_INVALID; - break; - case KM_BIGNUM: - case KM_BYTES: - set.params[i] = - keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); - break; - case KM_INVALID: - default: - set.params[i].tag = KM_TAG_INVALID; - /* just skip */ - break; - } - } - - return set; -} - -class KmParamSet : public keymaster_key_param_set_t { - public: - explicit KmParamSet(const hidl_vec& keyParams) - : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} - KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { - other.length = 0; - other.params = nullptr; - } - KmParamSet(const KmParamSet&) = delete; - ~KmParamSet() { delete[] params; } -}; - EVP_PKEY* RSA_fromMaterial(const uint8_t* modulus, size_t mod_size) { BIGNUM *n = BN_bin2bn(modulus, mod_size, NULL); BIGNUM *e = BN_new();//bignum_decode(exp, 5); @@ -232,11 +111,18 @@ keymaster_error_t JavaCardSoftKeymasterContext::LoadKey(const keymaster_algorith if(algorithm == KM_ALGORITHM_RSA) { pkey = RSA_fromMaterial(tmp, temp_size); } else if(algorithm == KM_ALGORITHM_EC) { - keymaster_ec_curve_t ec_curve = KM_EC_CURVE_P_256; + keymaster_ec_curve_t ec_curve; + uint32_t keySize; if (!hw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve) && !sw_enforced.GetTagValue(TAG_EC_CURVE, &ec_curve)) { - return KM_ERROR_INVALID_ARGUMENT; - }//TODO also get ec_curve based on key size + if(!hw_enforced.GetTagValue(TAG_KEY_SIZE, &keySize) && + !sw_enforced.GetTagValue(TAG_KEY_SIZE, &keySize)) { + return KM_ERROR_INVALID_ARGUMENT; + } + error = EcKeySizeToCurve(keySize, &ec_curve); + if(error != KM_ERROR_OK) + return error; + } pkey = EC_fromMaterial(tmp, temp_size, ec_curve); } if (!pkey) @@ -270,10 +156,13 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB AuthorizationSet hw_enforced; AuthorizationSet sw_enforced; KeymasterKeyBlob key_material; - keymaster_error_t error; + keymaster_error_t error = KM_ERROR_OK; auto constructKey = [&, this] () mutable -> keymaster_error_t { keymaster_algorithm_t algorithm; + if(error != KM_ERROR_OK) { + return error; + } if (!hw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm) && !sw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm)) { return KM_ERROR_INVALID_ARGUMENT; @@ -291,43 +180,24 @@ keymaster_error_t JavaCardSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyB std::unique_ptr item; ErrorCode errorCode = ErrorCode::UNKNOWN_ERROR; std::vector cborKey(blob.key_material_size); -// std::vector cborKey(187); for(size_t i = 0; i < blob.key_material_size; i++) { cborKey[i] = blob.key_material[i]; } -/*uint8_t tempBlob[] = {0x85, 0x58, 0x20, 0xDA, 0x29, 0xC7, 0x1A, 0x8C, 0xE7, 0x6A, 0x0D, 0xFD, -0x2E, 0x53, 0x06, 0x81, 0x85, 0x37, 0x2D, 0x9E, 0x74, 0xE7, 0xF1, 0xD5, -0x3F, 0x0E, 0xAB, 0x1A, 0xF8, 0xE9, 0x46, 0xFD, 0xDC, 0x37, 0x54, 0x4C, -0xE9, 0xA7, 0xD0, 0x71, 0x96, 0xCC, 0x66, 0x18, 0xF0, 0x53, 0xD1, 0x30, -0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x82, 0xA1, 0x1A, 0x30, 0x00, 0x01, 0xF5, 0x1A, 0x01, 0x02, 0x03, -0x04, 0xA6, 0x1A, 0x10, 0x00, 0x00, 0x02, 0x03, 0x1A, 0x50, 0x00, 0x00, -0xC8, 0x1A, 0x00, 0x01, 0x00, 0x01, 0x1A, 0x30, 0x00, 0x00, 0x03, 0x19, -0x01, 0x00, 0x1A, 0x10, 0x00, 0x02, 0xBE, 0x00, 0x1A, 0x30, 0x00, 0x02, -0xC1, 0x00, 0x1A, 0x30, 0x00, 0x02, 0xC2, 0x1A, 0x00, 0x03, 0x15, 0x14, -0x58, 0x41, 0x04, 0x2B, 0xF1, 0x84, 0xD4, 0xFB, 0x63, 0x44, 0x20, 0xD0, -0xA3, 0x7D, 0x6A, 0xC1, 0xC5, 0x26, 0x12, 0xCD, 0x79, 0x77, 0x81, 0x22, -0x33, 0x30, 0x70, 0xF7, 0x25, 0x6D, 0x75, 0xE0, 0xD4, 0xD0, 0x50, 0xD6, -0x80, 0x65, 0x2A, 0x44, 0x0B, 0x8E, 0xFC, 0xA0, 0x8B, 0xC5, 0xF4, 0x8A, -0xCA, 0x4B, 0x89, 0x6E, 0x8B, 0xFC, 0x38, 0xB7, 0xC9, 0xB9, 0xB6, 0xE7, -0x57, 0xE6, 0x53, 0xE9, 0xBF, 0x94, 0x3A}; - for(size_t i = 0; i < 187; i++) { - cborKey[i] = tempBlob[i]; - } -*/ std::tie(item, errorCode) = cc.decodeData(cborKey, false); if (item != nullptr) { - std::vector temp; - cc.getBinaryArray(item, 4, temp); - - key_material = {temp.data(), temp.size()}; - temp.clear(); + std::vector temp(0); + if(cc.getBinaryArray(item, 4, temp)) { + key_material = {temp.data(), temp.size()}; + temp.clear(); + } KeyCharacteristics keyCharacteristics; cc.getKeyCharacteristics(item, 3, keyCharacteristics); sw_enforced.Reinitialize(KmParamSet(keyCharacteristics.softwareEnforced)); hw_enforced.Reinitialize(KmParamSet(keyCharacteristics.hardwareEnforced)); + } else { + error = KM_ERROR_INVALID_KEY_BLOB; } return constructKey(); } diff --git a/HAL/keymaster/Android.bp b/HAL/keymaster/Android.bp index 33136850..bd253b43 100644 --- a/HAL/keymaster/Android.bp +++ b/HAL/keymaster/Android.bp @@ -20,6 +20,7 @@ cc_library { "4.1/CborConverter.cpp", "4.1/java_card_soft_keymaster_context.cpp", "4.1/JavacardOperationContext.cpp", + "4.1/CommonUtils.cpp", ], local_include_dirs: [ "include", diff --git a/HAL/keymaster/include/CborConverter.h b/HAL/keymaster/include/CborConverter.h index 08208ee1..9ea2ef94 100644 --- a/HAL/keymaster/include/CborConverter.h +++ b/HAL/keymaster/include/CborConverter.h @@ -54,7 +54,7 @@ class CborConverter const uint8_t* pos; std::unique_ptr item(nullptr); std::string message; - T errorCode = T::UNKNOWN_ERROR; + T errorCode = T::OK; std::tie(item, pos, message) = parse(response); @@ -138,13 +138,13 @@ class CborConverter * Get the list of binary arrays at the given position from the item pointer. */ bool getMultiBinaryArray(const std::unique_ptr& item, const uint32_t pos, - ::android::hardware::hidl_vec<::android::hardware::hidl_vec>& data); + std::vector>& data); /** * Add VerificationToken value to the Array item. */ bool addVerificationToken(Array& array, const VerificationToken& - verificationToken); + verificationToken, std::vector& encodedParamsVerified); /** * Get the ErrorCode value at the give position from the item pointer. diff --git a/HAL/keymaster/include/CommonUtils.h b/HAL/keymaster/include/CommonUtils.h new file mode 100644 index 00000000..a3feee14 --- /dev/null +++ b/HAL/keymaster/include/CommonUtils.h @@ -0,0 +1,98 @@ +/* + ** + ** Copyright 2020, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + + +#ifndef KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ +#define KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ + +#include +#include +#include + +namespace keymaster { +namespace V4_1 { +namespace javacard { +using ::android::hardware::hidl_vec; +using ::android::hardware::keymaster::V4_0::ErrorCode; +using ::android::hardware::keymaster::V4_0::Tag; +using ::android::hardware::keymaster::V4_0::KeyFormat; +using ::android::hardware::keymaster::V4_0::KeyParameter; +using ::android::hardware::keymaster::V4_0::KeyPurpose; +using ::android::hardware::keymaster::V4_0::EcCurve; + +inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { + return static_cast(value); +} + +inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { + return static_cast(value); +} + +inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { + return static_cast(value); +} + +inline keymaster_tag_t legacy_enum_conversion(const Tag value) { + return keymaster_tag_t(value); +} + +inline Tag legacy_enum_conversion(const keymaster_tag_t value) { + return Tag(value); +} + +inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { + hidl_vec result; + result.setToExternal(const_cast(buf.peek_read()), buf.available_read()); + return result; +} + +inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { + for(int i = 0; i < size; ++i) { + to.push_back(from[i]); + } +} + +keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams); + +hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set); + +ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& +pubModulus); + +ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& +publicKey, EcCurve& eccurve); + +class KmParamSet : public keymaster_key_param_set_t { + public: + explicit KmParamSet(const hidl_vec& keyParams) + : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} + KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { + other.length = 0; + other.params = nullptr; + } + KmParamSet(const KmParamSet&) = delete; + ~KmParamSet() { delete[] params; } +}; + +} // namespace javacard +} // namespace V4_1 +} // namespace keymaster +#endif //KEYMASTER_V4_1_JAVACARD_COMMONUTILS_H_ diff --git a/HAL/keymaster/include/JavacardKeymaster4Device.h b/HAL/keymaster/include/JavacardKeymaster4Device.h index 95299956..c7c06ed5 100644 --- a/HAL/keymaster/include/JavacardKeymaster4Device.h +++ b/HAL/keymaster/include/JavacardKeymaster4Device.h @@ -85,18 +85,22 @@ class JavacardKeymaster4Device : public IKeymasterDevice { Return deviceLocked(bool passwordOnly, const VerificationToken& verificationToken) override; Return earlyBootEnded() override; - //Helper methods. - bool getBootParamsInitialized() { return setUpBootParams; } - void setBootParams(bool flag) { setUpBootParams = flag; } + //Set Boot Params + /* This method should be called at the time when HAL is initialized for the first time */ + static ErrorCode setBootParams(uint32_t osVersion, uint32_t osPatchLevel, const std::vector& verifiedBootKey, +std::vector& verifiedBootKeyHash, keymaster_verified_boot_t kmVerifiedBoot, bool deviceLocked); + + //Provision Method + /* Reference for vendor to provision the javacard. This should happen only once at the time of production.*/ + static ErrorCode provision(const hidl_vec& keyParams, KeyFormat keyformat, const hidl_vec& +keyData); protected: CborConverter cborConverter_; - std::unique_ptr pTransportFactory; private: std::unique_ptr<::keymaster::AndroidKeymaster> softKm_; std::unique_ptr oprCtx_; - bool setUpBootParams; }; } // namespace javacard diff --git a/HAL/keymaster/include/JavacardOperationContext.h b/HAL/keymaster/include/JavacardOperationContext.h index d78b1aea..7a6fb706 100644 --- a/HAL/keymaster/include/JavacardOperationContext.h +++ b/HAL/keymaster/include/JavacardOperationContext.h @@ -96,9 +96,11 @@ class OperationContext { opr, out))) { return errorCode; } + if(finish || out.size() > 0) { - if(ErrorCode::OK != (errorCode = cb(out, finish))) { - return errorCode; + if(ErrorCode::OK != (errorCode = cb(out, finish))) { + return errorCode; + } } } else { /* Asymmetric */ diff --git a/HAL/keymaster/include/java_card_soft_keymaster_context.h b/HAL/keymaster/include/java_card_soft_keymaster_context.h index 07be5c9e..0fa2d711 100644 --- a/HAL/keymaster/include/java_card_soft_keymaster_context.h +++ b/HAL/keymaster/include/java_card_soft_keymaster_context.h @@ -19,16 +19,6 @@ #include -#include -#include - -#include -#include -#include -#include -#include -#include - namespace keymaster { class SoftKeymasterKeyRegistrations; @@ -53,13 +43,6 @@ class JavaCardSoftKeymasterContext : public keymaster::PureSoftKeymasterContext keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params, UniquePtr* key) const override; - /********************************************************************************************* - * Implement SoftwareKeyBlobMaker - */ - keymaster_error_t CreateKeyBlob(const AuthorizationSet& auths, keymaster_key_origin_t origin, - const KeymasterKeyBlob& key_material, KeymasterKeyBlob* blob, - AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const override; };