diff --git a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp index fa89ad8c..4204a8d7 100644 --- a/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp +++ b/HAL/keymaster/4.1/JavacardKeymaster4Device.cpp @@ -52,6 +52,8 @@ namespace keymaster { namespace V4_1 { namespace javacard { +//This key is used as master key for computing Hmac shared secret. +constexpr uint8_t kFakeKeyAgreementKey[32] = {}; static std::unique_ptr pTransportFactory = nullptr; constexpr size_t kOperationTableSize = 4; @@ -439,6 +441,8 @@ ErrorCode JavacardKeymaster4Device::provision(const hidl_vec& keyP std::vector subject; std::vector authorityKeyIdentifier; std::vector notAfter; + std::vector masterKey(kFakeKeyAgreementKey, kFakeKeyAgreementKey + + sizeof(kFakeKeyAgreementKey)/sizeof(kFakeKeyAgreementKey[0])); /* Subject, AuthorityKeyIdentifier and Expirty time of the root certificate are required by javacard. */ /* Get X509 certificate instance for the root certificate.*/ @@ -467,6 +471,7 @@ ErrorCode JavacardKeymaster4Device::provision(const hidl_vec& keyP array.add(subject); array.add(notAfter); array.add(authorityKeyIdentifier); + array.add(masterKey); std::vector cborData = array.encode(); if(ErrorCode::OK != (errorCode = constructApduMessage(ins, cborData, apdu))) @@ -1085,16 +1090,27 @@ Return JavacardKeymaster4Device::begin(KeyPurpose purpose, const hidl_vec< cborConverter_.addHardwareAuthToken(array, authToken); std::vector cborData = array.encode(); - /* keyCharacteristics.hardwareEnforced is required to store algorithm, digest and padding values in operationInfo - * structure. To retrieve keyCharacteristics.hardwareEnforced, parse the keyBlob. - */ - /* TODO if keyBlob is corrupted it crashes in cbor */ - std::tie(blobItem, errorCode) = cborConverter_.decodeData(std::vector(keyBlob), false); + // keyCharacteristics.hardwareEnforced is required to store algorithm, digest and padding values in operationInfo + // structure. To retrieve keyCharacteristics.hardwareEnforced, call getKeyCharacateristics. + // By calling getKeyCharacateristics also helps in finding a corrupted keyblob. + hidl_vec applicationId; + hidl_vec applicationData; + if(getTag(inParams, Tag::APPLICATION_ID, param)) { + applicationId = param.blob; + } + if(getTag(inParams, Tag::APPLICATION_DATA, param)) { + applicationData = param.blob; + } + //Call to getKeyCharacteristics. + getKeyCharacteristics(keyBlob, applicationId, applicationData, + [&](ErrorCode error, KeyCharacteristics keyChars) { + errorCode = error; + keyCharacteristics = keyChars; + }); - if(blobItem != nullptr) { + if(errorCode == ErrorCode::OK) { errorCode = ErrorCode::UNKNOWN_ERROR; - if(cborConverter_.getKeyCharacteristics(blobItem, 3, keyCharacteristics) && - getTag(keyCharacteristics.hardwareEnforced, Tag::ALGORITHM, param)) { + if(getTag(keyCharacteristics.hardwareEnforced, Tag::ALGORITHM, param)) { 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. diff --git a/HAL/keymaster/4.1/JavacardOperationContext.cpp b/HAL/keymaster/4.1/JavacardOperationContext.cpp index 6b43790e..457a6d87 100644 --- a/HAL/keymaster/4.1/JavacardOperationContext.cpp +++ b/HAL/keymaster/4.1/JavacardOperationContext.cpp @@ -16,6 +16,7 @@ */ #include +#include #define MAX_ALLOWED_INPUT_SIZE 512 #define AES_BLOCK_SIZE 16 @@ -203,12 +204,12 @@ ErrorCode OperationContext::finish(uint64_t operHandle, const std::vector& out) { - int dataToSELen = 0; - int inputConsumed = 0;/*Length of the data consumed from input */ - int blockSize = 0; + size_t dataToSELen = 0; + size_t inputConsumed = 0;/*Length of the data consumed from input */ + size_t blockSize = 0; BufferedData& data = operationTable[operHandle].data; int bufIndex = data.buf_len; @@ -228,19 +229,21 @@ ErrorCode OperationContext::getBlockAlignedData(uint64_t operHandle, uint8_t* in } else { /*Update */ //Calculate the block sized length on combined input of both buffered data and input data. - uint32_t blockAlignedLen = ((data.buf_len + input_len)/blockSize) * blockSize; - //For symmetric ciphers, decryption operation and PKCS7 padding mode save last 16 bytes of block and send this - //block in finish operation. This is done to make sure that there will be always a 16 bytes data to finish - //operation so that javacard Applet may remove PKCS7 padding if any. + size_t blockAlignedLen = ((data.buf_len + input_len)/blockSize) * blockSize; + //For symmetric ciphers, decryption operation and PKCS7 padding mode or AES GCM operation save the last 16 bytes + //of block and send this block in finish operation. This is done to make sure that there will be always a 16 + //bytes of data left for finish operation so that javacard Applet may remove PKCS7 padding if any or get the tag + //data for AES GCM operation for authentication purpose. if(((operationTable[operHandle].info.alg == Algorithm::AES) || (operationTable[operHandle].info.alg == Algorithm::TRIPLE_DES)) && - (operationTable[operHandle].info.pad == PaddingMode::PKCS7) && + (operationTable[operHandle].info.pad == PaddingMode::PKCS7 || + operationTable[operHandle].info.mode == BlockMode::GCM) && (operationTable[operHandle].info.purpose == KeyPurpose::DECRYPT)) { if(blockAlignedLen >= blockSize) blockAlignedLen -= blockSize; } //Copy data to be send to SE from buffer, only if atleast a minimum block aligned size is available. if(blockAlignedLen >= blockSize) { - for(size_t pos = 0; pos < data.buf_len; pos++) { + for(size_t pos = 0; pos < std::min(blockAlignedLen, data.buf_len); pos++) { out.push_back(data.buf[pos]); } } @@ -248,7 +251,9 @@ ErrorCode OperationContext::getBlockAlignedData(uint64_t operHandle, uint8_t* in } if(dataToSELen > 0) { - inputConsumed = dataToSELen - data.buf_len; + //If buffer length is greater than the data length to be send to SE, then input data consumed is 0. + //That means all the data to be send to SE is consumed from the buffer. + inputConsumed = (data.buf_len > dataToSELen) ? 0 : (dataToSELen - data.buf_len); //Copy the buffer to be send to SE. for(int i = 0; i < inputConsumed; i++) @@ -256,10 +261,18 @@ ErrorCode OperationContext::getBlockAlignedData(uint64_t operHandle, uint8_t* in out.push_back(input[i]); } - /* All the data is consumed so clear buffer */ - if(data.buf_len != 0) { - memset(data.buf, 0x00, sizeof(data.buf)); - bufIndex = data.buf_len = 0; + if(data.buf_len > dataToSELen) { + //Only blockAlignedLen data is consumed from buffer so reorder the buffer data. + memcpy(data.buf, data.buf+dataToSELen, data.buf_len-dataToSELen); + memset(data.buf+dataToSELen, 0x00, data.buf_len-dataToSELen); + data.buf_len -= dataToSELen; + bufIndex = data.buf_len; + } else { + // All the data is consumed so clear buffer + if(data.buf_len != 0) { + memset(data.buf, 0x00, sizeof(data.buf)); + bufIndex = data.buf_len = 0; + } } }