Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 177 additions & 52 deletions HAL/keymaster/4.1/CborConverter.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,76 +19,117 @@
#include <iostream>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <hidl/HidlSupport.h>
#include <CborConverter.h>

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<HardwareAuthenticatorType>(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<TAG>(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<TagType>(param.tag & (0xF << 28));
switch(tagType) {
case TagType::ENUM:
case TagType::ENUM_REP:
case TagType::UINT:
case TagType::UINT_REP:
map.add(static_cast<uint64_t>(param.tag), param.f.integer);
break;
case TagType::ULONG:
case TagType::ULONG_REP:
map.add(static_cast<uint64_t>(param.tag), param.f.longInteger);
break;
case TagType::DATE:
map.add(static_cast<uint64_t>(param.tag), param.f.dateTime);
break;
case TagType::BOOL:
map.add(static_cast<uint64_t>(param.tag), param.f.boolValue);
break;
case TagType::BIGNUM:
case TagType::BYTES:
map.add(static_cast<uint64_t>(param.tag), (std::vector<uint8_t>(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> &item, const uint32_t pos,
::android::hardware::keymaster::V4_0::KeyCharacteristics& keyCharacteristics) {
bool ret = false;
std::unique_ptr<Item> 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<Item>&,
const std::unique_ptr<Item>&> pair, KeyParameter& keyParam) {
const std::unique_ptr<Item>&> pair, KeyParameter& keyParam) {
bool ret = false;
uint64_t value;
//TAG will be always uint32_t
if (!getUint64<uint64_t>(pair.first, 0, value)) {
return ret;
}
if (!convertToTag(value, keyParam.tag)) return false;
keyParam.tag = static_cast<Tag>(value);

if (MajorType::UINT == getType(pair.second)) {
if (!getUint64<uint64_t>(pair.second, 0, value)) {
return ret;
TagType tagType = static_cast<TagType>(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<uint32_t>(value);
break;
case TagType::ULONG:
case TagType::ULONG_REP:
keyParam.f.longInteger = static_cast<uint32_t>(value);
break;
case TagType::DATE:
keyParam.f.dateTime = static_cast<uint32_t>(value);
break;
case TagType::BOOL:
keyParam.f.boolValue = static_cast<bool>(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<uint8_t> blob;
std::vector<uint8_t> 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;
}
Expand All@@ -97,9 +138,31 @@ ParseResult CborConverter::decodeData(const std::vector<uint8_t> cborData) {
return parse(cborData);
}

bool CborConverter::getMultiBinaryArray(const std::unique_ptr<Item>& item, const uint32_t pos,
::android::hardware::hidl_vec<::android::hardware::hidl_vec<uint8_t>>& data) {
bool ret = false;
std::unique_ptr<Item> 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<uint8_t> 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>& item, const uint32_t pos, std::vector<uint8_t>& value) {
bool ret = false;
const std::unique_ptr<Item>& strItem = getItemAtPos(item, pos);
std::unique_ptr<Item> strItem(nullptr);

getItemAtPos(item, pos, strItem);
if ((strItem == nullptr) && (MajorType::BSTR != getType(strItem)))
return ret;

Expand All@@ -115,19 +178,50 @@ bool CborConverter::getBinaryArray(const std::unique_ptr<Item>& item, const uint
bool CborConverter::getHmacSharingParameters(const std::unique_ptr<Item>& item, const uint32_t pos, HmacSharingParameters& params) {
std::vector<uint8_t> paramValue;
bool ret = false;
std::unique_ptr<Item> 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<uint64_t>(verificationToken.securityLevel));
array.add((std::vector<uint8_t>(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<uint64_t>(authToken.authenticatorType));
array.add(authToken.timestamp);
array.add((std::vector<uint8_t>(authToken.mac)));
return true;
}

bool CborConverter::getHardwareAuthToken(const std::unique_ptr<Item>& item, const uint32_t pos, HardwareAuthToken& token) {
bool ret = false;
std::vector<uint8_t> mac;
Expand All@@ -144,34 +238,65 @@ bool CborConverter::getHardwareAuthToken(const std::unique_ptr<Item>& item, cons
uint64_t authType;
if (!getUint64<uint64_t>(item, pos+3, authType))
return ret;
token.authenticatorType = convertToHardwareAuthenticatorType(authType);
token.authenticatorType = static_cast<HardwareAuthenticatorType>(authType);
//Timestamp
if (!getUint64<uint64_t>(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>& item, const uint32_t pos, VerificationToken&
token) {
bool ret = false;
std::vector<uint8_t> mac;
//challenge
if (!getUint64<uint64_t>(item, pos, token.challenge))
return ret;

//timestamp
if (!getUint64<uint64_t>(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<uint64_t>(item, pos+3, val))
return ret;
token.securityLevel = static_cast<SecurityLevel>(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>& item, const uint32_t pos, std::vector<KeyParameter> keyParams) {
bool CborConverter::getKeyParameters(const std::unique_ptr<Item>& item, const uint32_t pos, android::hardware::hidl_vec<::android::hardware::keymaster::V4_0::KeyParameter>& keyParams) {
bool ret = false;
const std::unique_ptr<Item>& mapItem = getItemAtPos(item, pos);
std::unique_ptr<Item> 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;
}

Loading