summaryrefslogtreecommitdiff
path: root/KM300/CborConverter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KM300/CborConverter.cpp')
-rw-r--r--KM300/CborConverter.cpp521
1 files changed, 0 insertions, 521 deletions
diff --git a/KM300/CborConverter.cpp b/KM300/CborConverter.cpp
deleted file mode 100644
index 61bcf8c..0000000
--- a/KM300/CborConverter.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- **
- ** 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 "CborConverter.h"
-
-#include <map>
-#include <string>
-
-#include <android-base/logging.h>
-
-#include <KeyMintUtils.h>
-
-namespace keymint::javacard {
-using ::aidl::android::hardware::security::keymint::KeyParameterValue;
-using ::aidl::android::hardware::security::keymint::SecurityLevel;
-using ::aidl::android::hardware::security::keymint::km_utils::kmParam2Aidl;
-using ::aidl::android::hardware::security::keymint::km_utils::legacy_enum_conversion;
-using ::aidl::android::hardware::security::keymint::km_utils::typeFromTag;
-
-constexpr int SB_ENFORCED = 0;
-constexpr int TEE_ENFORCED = 1;
-constexpr int SW_ENFORCED = 2;
-
-namespace {
-
-template <KeyParameterValue::Tag aidl_tag>
-std::optional<uint32_t> aidlEnumVal2Uint32(const KeyParameterValue& value) {
- return (value.getTag() == aidl_tag)
- ? std::optional(static_cast<uint32_t>(value.get<aidl_tag>()))
- : std::nullopt;
-}
-
-std::optional<uint32_t> aidlEnumParam2Uint32(const KeyParameter& param) {
- auto tag = legacy_enum_conversion(param.tag);
- switch (tag) {
- case KM_TAG_PURPOSE:
- return aidlEnumVal2Uint32<KeyParameterValue::keyPurpose>(param.value);
- case KM_TAG_ALGORITHM:
- return aidlEnumVal2Uint32<KeyParameterValue::algorithm>(param.value);
- case KM_TAG_BLOCK_MODE:
- return aidlEnumVal2Uint32<KeyParameterValue::blockMode>(param.value);
- case KM_TAG_DIGEST:
- case KM_TAG_RSA_OAEP_MGF_DIGEST:
- return aidlEnumVal2Uint32<KeyParameterValue::digest>(param.value);
- case KM_TAG_PADDING:
- return aidlEnumVal2Uint32<KeyParameterValue::paddingMode>(param.value);
- case KM_TAG_EC_CURVE:
- return aidlEnumVal2Uint32<KeyParameterValue::ecCurve>(param.value);
- case KM_TAG_USER_AUTH_TYPE:
- return aidlEnumVal2Uint32<KeyParameterValue::hardwareAuthenticatorType>(param.value);
- case KM_TAG_ORIGIN:
- return aidlEnumVal2Uint32<KeyParameterValue::origin>(param.value);
- case KM_TAG_BLOB_USAGE_REQUIREMENTS:
- case KM_TAG_KDF:
- default:
- LOG(FATAL) << "Unknown or unused enum tag: Something is broken";
- return std::nullopt;
- }
-}
-
-} // namespace
-
-bool CborConverter::addAttestationKey(Array& array,
- const std::optional<AttestationKey>& attestationKey) {
- if (attestationKey.has_value()) {
- array.add(Bstr(attestationKey->keyBlob));
- addKeyparameters(array, attestationKey->attestKeyParams);
- array.add(Bstr(attestationKey->issuerSubjectName));
- } else {
- array.add(std::move(Bstr(vector<uint8_t>(0))));
- array.add(std::move(Map()));
- array.add(std::move(Bstr(vector<uint8_t>(0))));
- }
- return true;
-}
-
-bool CborConverter::addKeyparameters(Array& array, const vector<KeyParameter>& keyParams) {
- Map map;
- std::map<uint32_t, vector<uint8_t>> enum_repetition;
- std::map<uint32_t, Array> uint_repetition;
- for (auto& param : keyParams) {
- auto tag = legacy_enum_conversion(param.tag);
- switch (typeFromTag(tag)) {
- case KM_ENUM: {
- auto paramEnum = aidlEnumParam2Uint32(param);
- if (paramEnum.has_value()) {
- map.add(static_cast<uint32_t>(tag), *paramEnum);
- }
- break;
- }
- case KM_UINT:
- if (param.value.getTag() == KeyParameterValue::integer) {
- uint32_t intVal = param.value.get<KeyParameterValue::integer>();
- map.add(static_cast<uint32_t>(tag), intVal);
- }
- break;
- case KM_UINT_REP:
- if (param.value.getTag() == KeyParameterValue::integer) {
- uint32_t intVal = param.value.get<KeyParameterValue::integer>();
- uint_repetition[static_cast<uint32_t>(tag)].add(intVal);
- }
- break;
- case KM_ENUM_REP: {
- auto paramEnumRep = aidlEnumParam2Uint32(param);
- if (paramEnumRep.has_value()) {
- enum_repetition[static_cast<uint32_t>(tag)].push_back(*paramEnumRep);
- }
- break;
- }
- case KM_ULONG:
- if (param.value.getTag() == KeyParameterValue::longInteger) {
- uint64_t longVal = param.value.get<KeyParameterValue::longInteger>();
- map.add(static_cast<uint32_t>(tag), longVal);
- }
- break;
- case KM_ULONG_REP:
- if (param.value.getTag() == KeyParameterValue::longInteger) {
- uint64_t longVal = param.value.get<KeyParameterValue::longInteger>();
- uint_repetition[static_cast<uint32_t>(tag)].add(longVal);
- }
- break;
- case KM_DATE:
- if (param.value.getTag() == KeyParameterValue::dateTime) {
- uint64_t dateVal = param.value.get<KeyParameterValue::dateTime>();
- map.add(static_cast<uint32_t>(tag), dateVal);
- }
- break;
- case KM_BOOL:
- map.add(static_cast<uint32_t>(tag), 1 /* true */);
- break;
- case KM_BIGNUM:
- case KM_BYTES:
- if (param.value.getTag() == KeyParameterValue::blob) {
- const auto& value = param.value.get<KeyParameterValue::blob>();
- map.add(static_cast<uint32_t>(tag), value);
- }
- break;
- case KM_INVALID:
- break;
- }
- }
-
- for (auto const& [key, val] : enum_repetition) {
- Bstr bstr(val);
- map.add(key, std::move(bstr));
- }
-
- for (auto& [key, val] : uint_repetition) {
- map.add(key, std::move(val));
- }
- array.add(std::move(map));
- return true;
-}
-
-// Array of three maps
-std::optional<vector<KeyCharacteristics>>
-CborConverter::getKeyCharacteristics(const unique_ptr<Item>& item, const uint32_t pos) {
- vector<KeyCharacteristics> keyCharacteristics;
- auto arrayItem = getItemAtPos(item, pos);
- if (!arrayItem || (MajorType::ARRAY != getType(arrayItem.value()))) {
- return std::nullopt;
- }
- KeyCharacteristics swEnf{SecurityLevel::KEYSTORE, {}};
- KeyCharacteristics teeEnf{SecurityLevel::TRUSTED_ENVIRONMENT, {}};
- KeyCharacteristics sbEnf{SecurityLevel::STRONGBOX, {}};
-
- auto optSbEnf = getKeyParameters(arrayItem.value(), SB_ENFORCED);
- if (!optSbEnf) {
- return std::nullopt;
- }
- sbEnf.authorizations = std::move(optSbEnf.value());
- auto optTeeEnf = getKeyParameters(arrayItem.value(), TEE_ENFORCED);
- if (!optTeeEnf) {
- return std::nullopt;
- }
- teeEnf.authorizations = std::move(optTeeEnf.value());
- auto optSwEnf = getKeyParameters(arrayItem.value(), SW_ENFORCED);
- if (!optSwEnf) {
- return std::nullopt;
- }
- swEnf.authorizations = std::move(optSwEnf.value());
- // VTS will fail if the authorizations list is empty.
- if (!sbEnf.authorizations.empty()) keyCharacteristics.push_back(std::move(sbEnf));
- if (!teeEnf.authorizations.empty()) keyCharacteristics.push_back(std::move(teeEnf));
- if (!swEnf.authorizations.empty()) keyCharacteristics.push_back(std::move(swEnf));
- return keyCharacteristics;
-}
-
-std::optional<std::vector<KeyParameter>> CborConverter::getKeyParameter(
- const std::pair<const std::unique_ptr<Item>&, const std::unique_ptr<Item>&> pair) {
- std::vector<KeyParameter> keyParams;
- keymaster_tag_t key;
- auto optValue = getUint64(pair.first);
- if (!optValue) {
- return std::nullopt;
- }
- key = static_cast<keymaster_tag_t>(optValue.value());
- switch (keymaster_tag_get_type(key)) {
- case KM_ENUM_REP: {
- /* ENUM_REP contains values encoded in a Byte string */
- const Bstr* bstr = pair.second.get()->asBstr();
- if (bstr == nullptr) {
- return std::nullopt;
- }
- for (auto bchar : bstr->value()) {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- keyParam.enumerated = bchar;
- keyParams.push_back(kmParam2Aidl(keyParam));
- }
- return keyParams;
- }
- case KM_ENUM: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- if (!(optValue = getUint64(pair.second))) {
- return std::nullopt;
- }
- keyParam.enumerated = static_cast<uint32_t>(optValue.value());
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_UINT: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- if (!(optValue = getUint64(pair.second))) {
- return std::nullopt;
- }
- keyParam.integer = static_cast<uint32_t>(optValue.value());
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_ULONG: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- if (!(optValue = getUint64(pair.second))) {
- return std::nullopt;
- }
- keyParam.long_integer = optValue.value();
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_UINT_REP: {
- /* UINT_REP contains values encoded in a Array */
- Array* array = const_cast<Array*>(pair.second.get()->asArray());
- if (array == nullptr) return std::nullopt;
- for (int i = 0; i < array->size(); i++) {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- const std::unique_ptr<Item>& item = array->get(i);
- if (!(optValue = getUint64(item))) {
- return std::nullopt;
- }
- keyParam.integer = static_cast<uint32_t>(optValue.value());
- keyParams.push_back(kmParam2Aidl(keyParam));
- }
- return keyParams;
- }
- case KM_ULONG_REP: {
- /* ULONG_REP contains values encoded in a Array */
- Array* array = const_cast<Array*>(pair.second.get()->asArray());
- if (array == nullptr) return std::nullopt;
- for (int i = 0; i < array->size(); i++) {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- const std::unique_ptr<Item>& item = array->get(i);
- if (!(optValue = getUint64(item))) {
- return std::nullopt;
- }
- keyParam.long_integer = optValue.value();
- keyParams.push_back(kmParam2Aidl(keyParam));
- }
- return keyParams;
- }
- case KM_DATE: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- if (!(optValue = getUint64(pair.second))) {
- return std::nullopt;
- }
- keyParam.date_time = optValue.value();
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_BOOL: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- if (!(optValue = getUint64(pair.second))) {
- return std::nullopt;
- }
- // If a tag with this type is present, the value is true. If absent,
- // false.
- keyParam.boolean = true;
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_BIGNUM:
- case KM_BYTES: {
- keymaster_key_param_t keyParam;
- keyParam.tag = key;
- const Bstr* bstr = pair.second.get()->asBstr();
- if (bstr == nullptr) return std::nullopt;
- keyParam.blob.data = bstr->value().data();
- keyParam.blob.data_length = bstr->value().size();
- keyParams.push_back(kmParam2Aidl(keyParam));
- return keyParams;
- }
- case KM_INVALID:
- break;
- }
- return std::nullopt;
-}
-
-// array of a blobs
-std::optional<vector<Certificate>>
-CborConverter::getCertificateChain(const std::unique_ptr<Item>& item, const uint32_t pos) {
- vector<Certificate> certChain;
- auto arrayItem = getItemAtPos(item, pos);
- if (!arrayItem || (MajorType::ARRAY != getType(arrayItem.value()))) return std::nullopt;
-
- const Array* arr = arrayItem.value().get()->asArray();
- for (int i = 0; i < arr->size(); i++) {
- Certificate cert;
- auto optTemp = getByteArrayVec(arrayItem.value(), i);
- if (!optTemp) return std::nullopt;
- cert.encodedCertificate = std::move(optTemp.value());
- certChain.push_back(std::move(cert));
- }
- return certChain;
-}
-
-std::optional<string> CborConverter::getTextStr(const unique_ptr<Item>& item, const uint32_t pos) {
- auto textStrItem = getItemAtPos(item, pos);
- if (!textStrItem || (MajorType::TSTR != getType(textStrItem.value()))) {
- return std::nullopt;
- }
- const Tstr* tstr = textStrItem.value().get()->asTstr();
- return tstr->value();
-}
-
-std::optional<string> CborConverter::getByteArrayStr(const unique_ptr<Item>& item,
- const uint32_t pos) {
- auto optTemp = getByteArrayVec(item, pos);
- if (!optTemp) {
- return std::nullopt;
- }
- std::string str(optTemp->begin(), optTemp->end());
- return str;
-}
-
-std::optional<std::vector<uint8_t>> CborConverter::getByteArrayVec(const unique_ptr<Item>& item,
- const uint32_t pos) {
- auto strItem = getItemAtPos(item, pos);
- if (!strItem || (MajorType::BSTR != getType(strItem.value()))) {
- return std::nullopt;
- }
- const Bstr* bstr = strItem.value().get()->asBstr();
- return bstr->value();
-}
-
-std::optional<SharedSecretParameters>
-CborConverter::getSharedSecretParameters(const unique_ptr<Item>& item, const uint32_t pos) {
- SharedSecretParameters params;
- // Array [seed, nonce]
- auto arrayItem = getItemAtPos(item, pos);
- if (!arrayItem || (MajorType::ARRAY != getType(arrayItem.value()))) {
- return std::nullopt;
- }
- auto optSeed = getByteArrayVec(arrayItem.value(), 0);
- auto optNonce = getByteArrayVec(arrayItem.value(), 1);
- if (!optSeed || !optNonce) {
- return std::nullopt;
- }
- params.seed = std::move(optSeed.value());
- params.nonce = std::move(optNonce.value());
- return params;
-}
-
-bool CborConverter::addSharedSecretParameters(Array& array,
- const vector<SharedSecretParameters>& params) {
- Array cborParamsVec;
- for (auto param : params) {
- Array cborParam;
- cborParam.add(Bstr(param.seed));
- cborParam.add(Bstr(param.nonce));
- cborParamsVec.add(std::move(cborParam));
- }
- array.add(std::move(cborParamsVec));
- return true;
-}
-
-bool CborConverter::addTimeStampToken(Array& array, const TimeStampToken& token) {
- Array vToken;
- vToken.add(static_cast<uint64_t>(token.challenge));
- vToken.add(static_cast<uint64_t>(token.timestamp.milliSeconds));
- vToken.add((std::vector<uint8_t>(token.mac)));
- array.add(std::move(vToken));
- return true;
-}
-
-bool CborConverter::addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken) {
- Array hwAuthToken;
- hwAuthToken.add(static_cast<uint64_t>(authToken.challenge));
- hwAuthToken.add(static_cast<uint64_t>(authToken.userId));
- hwAuthToken.add(static_cast<uint64_t>(authToken.authenticatorId));
- hwAuthToken.add(static_cast<uint64_t>(authToken.authenticatorType));
- hwAuthToken.add(static_cast<uint64_t>(authToken.timestamp.milliSeconds));
- hwAuthToken.add((std::vector<uint8_t>(authToken.mac)));
- array.add(std::move(hwAuthToken));
- return true;
-}
-
-std::optional<TimeStampToken> CborConverter::getTimeStampToken(const unique_ptr<Item>& item,
- const uint32_t pos) {
- TimeStampToken token;
- // {challenge, timestamp, Mac}
- auto optChallenge = getUint64(item, pos);
- auto optTimestampMillis = getUint64(item, pos + 1);
- auto optTemp = getByteArrayVec(item, pos + 2);
- if (!optChallenge || !optTimestampMillis || !optTemp) {
- return std::nullopt;
- }
- token.mac = std::move(optTemp.value());
- token.challenge = static_cast<long>(std::move(optChallenge.value()));
- token.timestamp.milliSeconds = static_cast<long>(std::move(optTimestampMillis.value()));
- return token;
-}
-
-std::optional<Array> CborConverter::getArrayItem(const std::unique_ptr<Item>& item,
- const uint32_t pos) {
- Array array;
- auto arrayItem = getItemAtPos(item, pos);
- if (!arrayItem || (MajorType::ARRAY != getType(arrayItem.value()))) {
- return std::nullopt;
- }
- array = std::move(*(arrayItem.value().get()->asArray()));
- return array;
-}
-
-std::optional<Map> CborConverter::getMapItem(const std::unique_ptr<Item>& item,
- const uint32_t pos) {
- Map map;
- auto mapItem = getItemAtPos(item, pos);
- if (!mapItem || (MajorType::MAP != getType(mapItem.value()))) {
- return std::nullopt;
- }
- map = std::move(*(mapItem.value().get()->asMap()));
- return map;
-}
-
-std::optional<vector<KeyParameter>> CborConverter::getKeyParameters(const unique_ptr<Item>& item,
- const uint32_t pos) {
- vector<KeyParameter> params;
- auto mapItem = getItemAtPos(item, pos);
- if (!mapItem || (MajorType::MAP != getType(mapItem.value()))) return std::nullopt;
- const Map* map = mapItem.value().get()->asMap();
- size_t mapSize = map->size();
- for (int i = 0; i < mapSize; i++) {
- auto optKeyParams = getKeyParameter((*map)[i]);
- if (optKeyParams) {
- params.insert(params.end(), optKeyParams->begin(), optKeyParams->end());
- } else {
- return std::nullopt;
- }
- }
- return params;
-}
-
-std::tuple<std::unique_ptr<Item>, keymaster_error_t>
-CborConverter::decodeData(const std::vector<uint8_t>& response) {
- auto [item, pos, message] = cppbor::parse(response);
- if (!item || MajorType::ARRAY != getType(item)) {
- return {nullptr, KM_ERROR_UNKNOWN_ERROR};
- }
- auto optErrorCode = getErrorCode(item, 0);
- if (!optErrorCode) {
- return {nullptr, KM_ERROR_UNKNOWN_ERROR};
- }
- return {std::move(item), optErrorCode.value()};
-}
-
-std::optional<keymaster_error_t>
-CborConverter::getErrorCode(const std::unique_ptr<cppbor::Item>& item, const uint32_t pos) {
- auto optErrorVal = getUint64(item, pos);
- if (!optErrorVal) {
- return std::nullopt;
- }
- return static_cast<keymaster_error_t>(0 - optErrorVal.value());
-}
-
-std::optional<uint64_t> CborConverter::getUint64(const unique_ptr<Item>& item) {
- if ((item == nullptr) || (MajorType::UINT != getType(item))) {
- return std::nullopt;
- }
- const Uint* uintVal = item.get()->asUint();
- return uintVal->unsignedValue();
-}
-
-std::optional<uint64_t> CborConverter::getUint64(const unique_ptr<Item>& item, const uint32_t pos) {
- auto intItem = getItemAtPos(item, pos);
- if (!intItem) {
- return std::nullopt;
- }
- return getUint64(intItem.value());
-}
-
-} // namespace keymint::javacard