Keystore 2.0: Make compatiblity wrapper use union KeyParameters.
Test: N/A
Change-Id: I411d90a71c5722281f13c28d55961d571f2eec90
diff --git a/keystore2/src/km_compat/Android.bp b/keystore2/src/km_compat/Android.bp
index 01cf2cc..7ca6a63 100644
--- a/keystore2/src/km_compat/Android.bp
+++ b/keystore2/src/km_compat/Android.bp
@@ -56,6 +56,7 @@
"libcrypto",
"libhidlbase",
"libkeymaster4_1support",
+ "libkeymint_support",
"libkeystore2_crypto",
"libutils",
],
@@ -75,6 +76,7 @@
}
cc_test {
+ name: "keystore2_km_compat_test_cpp",
cflags: [
"-Wall",
"-Werror",
@@ -83,6 +85,7 @@
srcs: [
"certificate_test.cpp",
"gtest_main.cpp",
+ "parameter_conversion_test.cpp",
"slot_test.cpp",
],
shared_libs: [
@@ -97,9 +100,9 @@
"libcrypto",
"libhidlbase",
"libkeymaster4_1support",
+ "libkeymint_support",
"libkeystore2_crypto",
"libkm_compat",
"libutils",
],
- name: "keystore2_certificate_test",
}
diff --git a/keystore2/src/km_compat/certificate_test.cpp b/keystore2/src/km_compat/certificate_test.cpp
index d8c8c0a..9307569 100644
--- a/keystore2/src/km_compat/certificate_test.cpp
+++ b/keystore2/src/km_compat/certificate_test.cpp
@@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include "km_compat.h"
+#include <keymint_support/keymint_tags.h>
#include <aidl/android/hardware/security/keymint/Algorithm.h>
#include <aidl/android/hardware/security/keymint/BlockMode.h>
@@ -39,10 +40,15 @@
using ::aidl::android::hardware::security::keymint::SecurityLevel;
using ::aidl::android::hardware::security::keymint::Tag;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
static std::variant<std::vector<Certificate>, ScopedAStatus>
getCertificate(const std::vector<KeyParameter>& keyParams) {
static std::shared_ptr<KeyMintDevice> device =
KeyMintDevice::createKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
+ if (!device) {
+ return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+ }
ByteArray blob;
KeyCharacteristics characteristics;
std::vector<Certificate> certChain;
@@ -69,9 +75,9 @@
static std::vector<KeyParameter> getRSAKeyParams(const std::vector<KeyParameter>& extraParams) {
auto keyParams = std::vector<KeyParameter>({
- KeyParameter{.tag = Tag::ALGORITHM, .integer = static_cast<int32_t>(Algorithm::RSA)},
- KeyParameter{.tag = Tag::KEY_SIZE, .integer = 2048},
- KeyParameter{.tag = Tag::RSA_PUBLIC_EXPONENT, .longInteger = 65537},
+ KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::RSA),
+ KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 2048),
+ KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, 65537),
});
keyParams.insert(keyParams.end(), extraParams.begin(), extraParams.end());
return keyParams;
@@ -79,11 +85,11 @@
TEST(CertificateTest, TestRSAKeygen) {
auto keyParams = getRSAKeyParams({
- KeyParameter{.tag = Tag::DIGEST, .integer = static_cast<int32_t>(Digest::SHA_2_256)},
- KeyParameter{.tag = Tag::PADDING, .integer = static_cast<int32_t>(PaddingMode::RSA_PSS)},
- KeyParameter{.tag = Tag::NO_AUTH_REQUIRED, .boolValue = true},
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::SIGN)},
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::ENCRYPT)},
+ KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+ KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+ KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED),
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::ENCRYPT),
});
auto result = getCertificate(keyParams);
ensureCertChainSize(result, 1);
@@ -91,21 +97,21 @@
TEST(CertificateTest, TestAES) {
auto keyParams = {
- KeyParameter{.tag = Tag::ALGORITHM, .integer = static_cast<int32_t>(Algorithm::AES)},
- KeyParameter{.tag = Tag::KEY_SIZE, .integer = 128},
- KeyParameter{.tag = Tag::BLOCK_MODE, .integer = static_cast<int32_t>(BlockMode::CBC)},
- KeyParameter{.tag = Tag::PADDING, .integer = static_cast<int32_t>(PaddingMode::NONE)},
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::ENCRYPT)},
+ KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::AES),
+ KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 128),
+ KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, BlockMode::CBC),
+ KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::NONE),
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::ENCRYPT),
};
auto result = getCertificate(keyParams);
ensureCertChainSize(result, 0);
}
-TEST(CertificateTest, TestAttestion) {
+TEST(CertificateTest, TestAttestation) {
auto keyParams = getRSAKeyParams({
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::SIGN)},
- KeyParameter{.tag = Tag::ATTESTATION_CHALLENGE, .blob = {42}},
- KeyParameter{.tag = Tag::ATTESTATION_APPLICATION_ID, .blob = {42}},
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+ KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_CHALLENGE, 42),
+ KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_APPLICATION_ID, 42),
});
auto result = getCertificate(keyParams);
ensureCertChainSize(result, 3);
@@ -114,10 +120,10 @@
TEST(CertificateTest, TestRSAKeygenNoEncryptNoAuthRequired) {
auto keyParams = getRSAKeyParams({
- KeyParameter{.tag = Tag::DIGEST, .integer = static_cast<int32_t>(Digest::SHA_2_256)},
- KeyParameter{.tag = Tag::PADDING, .integer = static_cast<int32_t>(PaddingMode::RSA_PSS)},
- KeyParameter{.tag = Tag::NO_AUTH_REQUIRED, .boolValue = true},
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::SIGN)},
+ KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+ KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+ KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
});
auto result = getCertificate(keyParams);
ensureCertChainSize(result, 1);
@@ -126,9 +132,9 @@
TEST(CertificateTest, TestRSAKeygenNoEncryptAuthRequired) {
auto keyParams = getRSAKeyParams({
- KeyParameter{.tag = Tag::DIGEST, .integer = static_cast<int32_t>(Digest::SHA_2_256)},
- KeyParameter{.tag = Tag::PADDING, .integer = static_cast<int32_t>(PaddingMode::RSA_PSS)},
- KeyParameter{.tag = Tag::PURPOSE, .integer = static_cast<int32_t>(KeyPurpose::SIGN)},
+ KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+ KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+ KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
});
auto result = getCertificate(keyParams);
ensureCertChainSize(result, 1);
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 7900576..c9af80d 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -16,6 +16,7 @@
#include "km_compat.h"
+#include "km_compat_type_conversion.h"
#include <aidl/android/hardware/security/keymint/Algorithm.h>
#include <aidl/android/hardware/security/keymint/Digest.h>
#include <aidl/android/hardware/security/keymint/PaddingMode.h>
@@ -23,10 +24,12 @@
#include <android-base/logging.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <binder/IServiceManager.h>
+#include <hardware/keymaster_defs.h>
#include <keymasterV4_1/Keymaster.h>
#include <keymasterV4_1/Keymaster3.h>
#include <keymasterV4_1/Keymaster4.h>
-#include <keymasterV4_1/keymaster_tags.h>
+
+#include "certificate_utils.h"
using ::aidl::android::hardware::security::keymint::Algorithm;
using ::aidl::android::hardware::security::keymint::Digest;
@@ -42,6 +45,9 @@
using V4_0_KeyFormat = ::android::hardware::keymaster::V4_0::KeyFormat;
using V4_0_KeyParameter = ::android::hardware::keymaster::V4_0::KeyParameter;
using V4_0_VerificationToken = ::android::hardware::keymaster::V4_0::VerificationToken;
+namespace V4_0 = ::android::hardware::keymaster::V4_0;
+namespace V4_1 = ::android::hardware::keymaster::V4_1;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
// Utility functions
@@ -53,75 +59,13 @@
return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
}
-// TODO: The enum representation will need to be updated when we get unions.
-static V4_0_KeyParameter convertKeyParameterToLegacy(const KeyParameter& kp) {
- V4_0_KeyParameter lkp;
- lkp.tag = static_cast<::android::hardware::keymaster::V4_0::Tag>(kp.tag);
- switch (::android::hardware::keymaster::V4_0::typeFromTag(lkp.tag)) {
- case TagType::ENUM:
- case TagType::ENUM_REP:
- case TagType::UINT:
- case TagType::UINT_REP:
- lkp.f.integer = kp.integer;
- break;
- case TagType::ULONG:
- case TagType::ULONG_REP:
- lkp.f.longInteger = kp.longInteger;
- break;
- case TagType::DATE:
- lkp.f.dateTime = kp.longInteger;
- break;
- case TagType::BOOL:
- lkp.f.boolValue = kp.boolValue;
- break;
- case TagType::BIGNUM:
- case TagType::BYTES:
- lkp.blob = kp.blob;
- break;
- case TagType::INVALID:
- break;
- }
- return lkp;
-}
-
-static std::vector<V4_0_KeyParameter>
+static std::vector<V4_0::KeyParameter>
convertKeyParametersToLegacy(const std::vector<KeyParameter>& kps) {
- std::vector<V4_0_KeyParameter> legacyKps(kps.size());
+ std::vector<V4_0::KeyParameter> legacyKps(kps.size());
std::transform(kps.begin(), kps.end(), legacyKps.begin(), convertKeyParameterToLegacy);
return legacyKps;
}
-// TODO: The enum representation will need to be updated when we get unions.
-static KeyParameter convertKeyParameterFromLegacy(const V4_0_KeyParameter& lkp) {
- KeyParameter kp;
- kp.tag = static_cast<Tag>(lkp.tag);
- switch (::android::hardware::keymaster::V4_0::typeFromTag(lkp.tag)) {
- case TagType::ENUM:
- case TagType::ENUM_REP:
- case TagType::UINT:
- case TagType::UINT_REP:
- kp.integer = lkp.f.integer;
- break;
- case TagType::ULONG:
- case TagType::ULONG_REP:
- kp.longInteger = lkp.f.longInteger;
- break;
- case TagType::DATE:
- kp.longInteger = lkp.f.dateTime;
- break;
- case TagType::BOOL:
- kp.boolValue = lkp.f.boolValue;
- break;
- case TagType::BIGNUM:
- case TagType::BYTES:
- kp.blob = lkp.blob;
- break;
- case TagType::INVALID:
- break;
- }
- return kp;
-}
-
static std::vector<KeyParameter>
convertKeyParametersFromLegacy(const std::vector<V4_0_KeyParameter>& legacyKps) {
std::vector<KeyParameter> kps(legacyKps.size());
@@ -487,29 +431,32 @@
// Certificate implementation
-static std::optional<KeyParameter> getParam(const std::vector<KeyParameter>& keyParams, Tag tag) {
- auto it = find_if(keyParams.begin(), keyParams.end(),
- [&](const KeyParameter& kp) { return kp.tag == tag; });
- if (it == keyParams.end()) {
- return std::nullopt;
+template <KMV1::Tag tag, KMV1::TagType type>
+static auto getParam(const std::vector<KeyParameter>& keyParams, KMV1::TypedTag<type, tag> ttag)
+ -> decltype(authorizationValue(ttag, KeyParameter())) {
+ for (const auto& p : keyParams) {
+ if (auto v = authorizationValue(ttag, p)) {
+ return v;
+ }
}
- return std::optional(*it);
+ return {};
}
-static bool containsParam(const std::vector<KeyParameter>& keyParams, Tag tag) {
- return getParam(keyParams, tag).has_value();
+template <typename T>
+static bool containsParam(const std::vector<KeyParameter>& keyParams, T ttag) {
+ return static_cast<bool>(getParam(keyParams, ttag));
}
// Prefer the smallest.
// If no options are found, return the first.
template <typename T>
-static T getMaximum(const std::vector<KeyParameter>& keyParams, Tag tag,
- std::vector<T> sortedOptions) {
+static typename KMV1::TypedTag2ValueType<T>::type
+getMaximum(const std::vector<KeyParameter>& keyParams, T tag,
+ std::vector<typename KMV1::TypedTag2ValueType<T>::type> sortedOptions) {
auto bestSoFar = sortedOptions.end();
for (const KeyParameter& kp : keyParams) {
- if (kp.tag == tag) {
- auto it =
- std::find(sortedOptions.begin(), sortedOptions.end(), static_cast<T>(kp.integer));
+ if (auto value = authorizationValue(tag, kp)) {
+ auto it = std::find(sortedOptions.begin(), sortedOptions.end(), *value);
if (std::distance(it, bestSoFar) < 0) {
bestSoFar = it;
}
@@ -521,40 +468,23 @@
return *bestSoFar;
}
-// TODO: What should I do if these tags don't exist? An empty blob might be okay, but what about
-// the integers and longs?
-// TODO: Migrate to using accessTagValue when possible.
-static std::vector<uint8_t> getBlob(const std::optional<KeyParameter> kp) {
- if (!kp.has_value()) {
- return {};
- }
- return kp->blob;
-}
-
-static int32_t getLong(std::optional<KeyParameter> kp) {
- if (!kp.has_value()) {
- return -1;
- }
- return kp->longInteger;
-}
-
-static int64_t getInteger(std::optional<KeyParameter> kp) {
- if (!kp.has_value()) {
- return -1;
- }
- return kp->integer;
-}
-
static std::variant<keystore::X509_Ptr, V4_0_ErrorCode>
makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob) {
// Start generating the certificate.
// Get public key for makeCert.
- V4_0_ErrorCode errorCode = V4_0_ErrorCode::OK;
+ V4_0_ErrorCode errorCode;
std::vector<uint8_t> key;
+ static std::vector<uint8_t> empty_vector;
+ auto unwrapBlob = [&](auto b) -> const std::vector<uint8_t>& {
+ if (b)
+ return *b;
+ else
+ return empty_vector;
+ };
auto result = mDevice->exportKey(
- V4_0_KeyFormat::X509, keyBlob, getBlob(getParam(keyParams, Tag::APPLICATION_ID)),
- getBlob(getParam(keyParams, Tag::APPLICATION_DATA)),
+ V4_0_KeyFormat::X509, keyBlob, unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_ID)),
+ unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_DATA)),
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
errorCode = error;
key = keyMaterial;
@@ -572,13 +502,21 @@
// makeCert
// TODO: Get the serial and subject from key params once the tags are added. Also use new tags
// for the two datetime parameters once we get those.
+
+ uint64_t activation = 0;
+ if (auto date = getParam(keyParams, KMV1::TAG_ACTIVE_DATETIME)) {
+ activation = *date;
+ }
+ uint64_t expiration = std::numeric_limits<uint64_t>::max();
+ if (auto date = getParam(keyParams, KMV1::TAG_USAGE_EXPIRE_DATETIME)) {
+ expiration = *date;
+ }
+
auto certOrError = keystore::makeCert(
- pkey, 42, "TODO", getLong(getParam(keyParams, Tag::ACTIVE_DATETIME)),
- getLong(getParam(keyParams, Tag::USAGE_EXPIRE_DATETIME)),
- false /* intentionally left blank */, std::nullopt /* intentionally left blank */,
- std::nullopt /* intentionally left blank */);
+ pkey, 42, "TODO", activation, expiration, false /* intentionally left blank */,
+ std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */);
if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) {
- // TODO: What error should I actually return? And the same everywhere below.
+ LOG(ERROR) << __func__ << ": Failed to make certificate";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
return std::move(std::get<keystore::X509_Ptr>(certOrError));
@@ -591,6 +529,7 @@
case Algorithm::EC:
return keystore::Algo::ECDSA;
default:
+ LOG(ERROR) << __func__ << ": This should not be called with symmetric algorithm.";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
}
@@ -620,6 +559,7 @@
case Digest::SHA_2_512:
return keystore::Digest::SHA512;
default:
+ LOG(ERROR) << __func__ << ": Unknown digest.";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
}
@@ -627,21 +567,21 @@
std::optional<V4_0_ErrorCode>
KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob, X509* cert) {
- auto algorithm = static_cast<Algorithm>(getInteger(getParam(keyParams, Tag::ALGORITHM)));
- auto algoOrError = getKeystoreAlgorithm(algorithm);
+ auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
+ auto algoOrError = getKeystoreAlgorithm(*algorithm);
if (std::holds_alternative<V4_0_ErrorCode>(algoOrError)) {
return std::get<V4_0_ErrorCode>(algoOrError);
}
auto algo = std::get<keystore::Algo>(algoOrError);
- auto origPadding = getMaximum<PaddingMode>(
- keyParams, Tag::PADDING, {PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN});
+ auto origPadding = getMaximum(keyParams, KMV1::TAG_PADDING,
+ {PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN});
auto paddingOrError = getKeystorePadding(origPadding);
if (std::holds_alternative<V4_0_ErrorCode>(paddingOrError)) {
return std::get<V4_0_ErrorCode>(paddingOrError);
}
auto padding = std::get<keystore::Padding>(paddingOrError);
- auto origDigest = getMaximum<Digest>(
- keyParams, Tag::DIGEST,
+ auto origDigest = getMaximum(
+ keyParams, KMV1::TAG_DIGEST,
{Digest::SHA_2_256, Digest::SHA_2_512, Digest::SHA_2_384, Digest::SHA_2_224, Digest::SHA1});
auto digestOrError = getKeystoreDigest(origDigest);
if (std::holds_alternative<V4_0_ErrorCode>(digestOrError)) {
@@ -655,8 +595,8 @@
[&](const uint8_t* data, size_t len) {
std::vector<uint8_t> dataVec(data, data + len);
std::vector<KeyParameter> kps = {
- KeyParameter{.tag = Tag::PADDING, .integer = static_cast<int32_t>(origPadding)},
- KeyParameter{.tag = Tag::DIGEST, .integer = static_cast<int32_t>(origDigest)},
+ KMV1::makeKeyParameter(KMV1::TAG_PADDING, origPadding),
+ KMV1::makeKeyParameter(KMV1::TAG_DIGEST, origDigest),
};
BeginResult beginResult;
auto error = begin(KeyPurpose::SIGN, keyBlob, kps, HardwareAuthToken(), &beginResult);
@@ -683,6 +623,8 @@
},
algo, padding, digest);
if (error) {
+ LOG(ERROR) << __func__
+ << ": signCertWith failed. (Callback diagnosed: " << toString(errorCode) << ")";
return V4_0_ErrorCode::UNKNOWN_ERROR;
}
if (errorCode != V4_0_ErrorCode::OK) {
@@ -695,16 +637,21 @@
KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob) {
// There are no certificates for symmetric keys.
- auto algorithm = static_cast<Algorithm>(getInteger(getParam(keyParams, Tag::ALGORITHM)));
- switch (algorithm) {
+ auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
+ if (!algorithm) {
+ LOG(ERROR) << __func__ << ": Unable to determine key algorithm.";
+ return V4_0_ErrorCode::UNKNOWN_ERROR;
+ }
+ switch (*algorithm) {
case Algorithm::RSA:
case Algorithm::EC:
break;
default:
return V4_0_ErrorCode::OK;
}
+
// If attestation was requested, call and use attestKey.
- if (containsParam(keyParams, Tag::ATTESTATION_CHALLENGE)) {
+ if (containsParam(keyParams, KMV1::TAG_ATTESTATION_CHALLENGE)) {
auto legacyParams = convertKeyParametersToLegacy(keyParams);
std::vector<Certificate> certs;
V4_0_ErrorCode errorCode = V4_0_ErrorCode::OK;
@@ -743,10 +690,12 @@
// Signing
auto canSelfSign =
std::find_if(keyParams.begin(), keyParams.end(), [&](const KeyParameter& kp) {
- return kp.tag == Tag::PURPOSE &&
- static_cast<KeyPurpose>(kp.integer) == KeyPurpose::SIGN;
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_PURPOSE, kp)) {
+ return *v == KeyPurpose::SIGN;
+ }
+ return false;
}) != keyParams.end();
- auto noAuthRequired = containsParam(keyParams, Tag::NO_AUTH_REQUIRED);
+ auto noAuthRequired = containsParam(keyParams, KMV1::TAG_NO_AUTH_REQUIRED);
if (canSelfSign && noAuthRequired) {
auto errorCode = signCertificate(keyParams, keyBlob, &*cert);
if (errorCode.has_value()) {
@@ -900,13 +849,19 @@
std::shared_ptr<KeyMintDevice>
KeyMintDevice::createKeyMintDevice(KeyMintSecurityLevel securityLevel) {
- auto secLevel = static_cast<SecurityLevel>(securityLevel);
- auto devices = initializeKeymasters();
- auto device = devices[secLevel];
- if (!device) {
- return {};
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> lock(mutex);
+ static std::shared_ptr<KeyMintDevice> device_ptr;
+ if (!device_ptr) {
+ auto secLevel = static_cast<SecurityLevel>(securityLevel);
+ auto devices = initializeKeymasters();
+ auto device = devices[secLevel];
+ if (!device) {
+ return {};
+ }
+ device_ptr = ndk::SharedRefBase::make<KeyMintDevice>(std::move(device), securityLevel);
}
- return ndk::SharedRefBase::make<KeyMintDevice>(std::move(device), securityLevel);
+ return device_ptr;
}
ScopedAStatus
diff --git a/keystore2/src/km_compat/km_compat_service.cpp b/keystore2/src/km_compat/km_compat_service.cpp
index 56d7909..d2ced49 100644
--- a/keystore2/src/km_compat/km_compat_service.cpp
+++ b/keystore2/src/km_compat/km_compat_service.cpp
@@ -17,13 +17,24 @@
#include "km_compat.h"
#include <android/binder_manager.h>
+#include <mutex>
+
extern "C" {
// Create a KeyMintDevice and add it as a service.
int32_t addKeyMintDeviceService() {
- std::shared_ptr<KeystoreCompatService> ti = ndk::SharedRefBase::make<KeystoreCompatService>();
- const auto instanceName = "android.security.compat";
- binder_status_t status = AServiceManager_addService(ti->asBinder().get(), instanceName);
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> lock(mutex);
+ static std::shared_ptr<KeystoreCompatService> ti;
+ binder_status_t status = STATUS_OK;
+ if (!ti) {
+ ti = ndk::SharedRefBase::make<KeystoreCompatService>();
+ const auto instanceName = "android.security.compat";
+ status = AServiceManager_addService(ti->asBinder().get(), instanceName);
+ if (status != STATUS_OK) {
+ ti.reset();
+ }
+ }
return status;
}
}
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
new file mode 100644
index 0000000..97c61ce
--- /dev/null
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -0,0 +1,886 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#include <keymasterV4_1/keymaster_tags.h>
+#include <keymint_support/keymint_tags.h>
+
+namespace V4_0 = ::android::hardware::keymaster::V4_0;
+namespace V4_1 = ::android::hardware::keymaster::V4_1;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+static V4_0::KeyPurpose convert(KMV1::KeyPurpose p) {
+ switch (p) {
+ case KMV1::KeyPurpose::ENCRYPT:
+ return V4_0::KeyPurpose::ENCRYPT;
+ case KMV1::KeyPurpose::DECRYPT:
+ return V4_0::KeyPurpose::DECRYPT;
+ case KMV1::KeyPurpose::SIGN:
+ return V4_0::KeyPurpose::SIGN;
+ case KMV1::KeyPurpose::VERIFY:
+ return V4_0::KeyPurpose::VERIFY;
+ case KMV1::KeyPurpose::WRAP_KEY:
+ return V4_0::KeyPurpose::WRAP_KEY;
+ }
+}
+
+static KMV1::KeyPurpose convert(V4_0::KeyPurpose p) {
+ switch (p) {
+ case V4_0::KeyPurpose::ENCRYPT:
+ return KMV1::KeyPurpose::ENCRYPT;
+ case V4_0::KeyPurpose::DECRYPT:
+ return KMV1::KeyPurpose::DECRYPT;
+ case V4_0::KeyPurpose::SIGN:
+ return KMV1::KeyPurpose::SIGN;
+ case V4_0::KeyPurpose::VERIFY:
+ return KMV1::KeyPurpose::VERIFY;
+ case V4_0::KeyPurpose::WRAP_KEY:
+ return KMV1::KeyPurpose::WRAP_KEY;
+ }
+}
+
+static V4_0::Algorithm convert(KMV1::Algorithm a) {
+ switch (a) {
+ case KMV1::Algorithm::RSA:
+ return V4_0::Algorithm::RSA;
+ case KMV1::Algorithm::EC:
+ return V4_0::Algorithm::EC;
+ case KMV1::Algorithm::AES:
+ return V4_0::Algorithm::AES;
+ case KMV1::Algorithm::TRIPLE_DES:
+ return V4_0::Algorithm::TRIPLE_DES;
+ case KMV1::Algorithm::HMAC:
+ return V4_0::Algorithm::HMAC;
+ }
+}
+
+static KMV1::Algorithm convert(V4_0::Algorithm a) {
+ switch (a) {
+ case V4_0::Algorithm::RSA:
+ return KMV1::Algorithm::RSA;
+ case V4_0::Algorithm::EC:
+ return KMV1::Algorithm::EC;
+ case V4_0::Algorithm::AES:
+ return KMV1::Algorithm::AES;
+ case V4_0::Algorithm::TRIPLE_DES:
+ return KMV1::Algorithm::TRIPLE_DES;
+ case V4_0::Algorithm::HMAC:
+ return KMV1::Algorithm::HMAC;
+ }
+}
+
+static V4_0::Digest convert(KMV1::Digest d) {
+ switch (d) {
+ case KMV1::Digest::NONE:
+ return V4_0::Digest::NONE;
+ case KMV1::Digest::MD5:
+ return V4_0::Digest::MD5;
+ case KMV1::Digest::SHA1:
+ return V4_0::Digest::SHA1;
+ case KMV1::Digest::SHA_2_224:
+ return V4_0::Digest::SHA_2_224;
+ case KMV1::Digest::SHA_2_256:
+ return V4_0::Digest::SHA_2_256;
+ case KMV1::Digest::SHA_2_384:
+ return V4_0::Digest::SHA_2_384;
+ case KMV1::Digest::SHA_2_512:
+ return V4_0::Digest::SHA_2_512;
+ }
+}
+
+static KMV1::Digest convert(V4_0::Digest d) {
+ switch (d) {
+ case V4_0::Digest::NONE:
+ return KMV1::Digest::NONE;
+ case V4_0::Digest::MD5:
+ return KMV1::Digest::MD5;
+ case V4_0::Digest::SHA1:
+ return KMV1::Digest::SHA1;
+ case V4_0::Digest::SHA_2_224:
+ return KMV1::Digest::SHA_2_224;
+ case V4_0::Digest::SHA_2_256:
+ return KMV1::Digest::SHA_2_256;
+ case V4_0::Digest::SHA_2_384:
+ return KMV1::Digest::SHA_2_384;
+ case V4_0::Digest::SHA_2_512:
+ return KMV1::Digest::SHA_2_512;
+ }
+}
+
+static V4_0::EcCurve convert(KMV1::EcCurve e) {
+ switch (e) {
+ case KMV1::EcCurve::P_224:
+ return V4_0::EcCurve::P_224;
+ case KMV1::EcCurve::P_256:
+ return V4_0::EcCurve::P_256;
+ case KMV1::EcCurve::P_384:
+ return V4_0::EcCurve::P_384;
+ case KMV1::EcCurve::P_521:
+ return V4_0::EcCurve::P_521;
+ }
+}
+
+static KMV1::EcCurve convert(V4_0::EcCurve e) {
+ switch (e) {
+ case V4_0::EcCurve::P_224:
+ return KMV1::EcCurve::P_224;
+ case V4_0::EcCurve::P_256:
+ return KMV1::EcCurve::P_256;
+ case V4_0::EcCurve::P_384:
+ return KMV1::EcCurve::P_384;
+ case V4_0::EcCurve::P_521:
+ return KMV1::EcCurve::P_521;
+ }
+}
+
+static V4_0::BlockMode convert(KMV1::BlockMode b) {
+ switch (b) {
+ case KMV1::BlockMode::ECB:
+ return V4_0::BlockMode::ECB;
+ case KMV1::BlockMode::CBC:
+ return V4_0::BlockMode::CBC;
+ case KMV1::BlockMode::CTR:
+ return V4_0::BlockMode::CTR;
+ case KMV1::BlockMode::GCM:
+ return V4_0::BlockMode::GCM;
+ }
+}
+
+static KMV1::BlockMode convert(V4_0::BlockMode b) {
+ switch (b) {
+ case V4_0::BlockMode::ECB:
+ return KMV1::BlockMode::ECB;
+ case V4_0::BlockMode::CBC:
+ return KMV1::BlockMode::CBC;
+ case V4_0::BlockMode::CTR:
+ return KMV1::BlockMode::CTR;
+ case V4_0::BlockMode::GCM:
+ return KMV1::BlockMode::GCM;
+ }
+}
+
+static V4_0::PaddingMode convert(KMV1::PaddingMode p) {
+ switch (p) {
+ case KMV1::PaddingMode::NONE:
+ return V4_0::PaddingMode::NONE;
+ case KMV1::PaddingMode::RSA_OAEP:
+ return V4_0::PaddingMode::RSA_OAEP;
+ case KMV1::PaddingMode::RSA_PSS:
+ return V4_0::PaddingMode::RSA_PSS;
+ case KMV1::PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+ return V4_0::PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+ case KMV1::PaddingMode::RSA_PKCS1_1_5_SIGN:
+ return V4_0::PaddingMode::RSA_PKCS1_1_5_SIGN;
+ case KMV1::PaddingMode::PKCS7:
+ return V4_0::PaddingMode::PKCS7;
+ }
+}
+
+static KMV1::PaddingMode convert(V4_0::PaddingMode p) {
+ switch (p) {
+ case V4_0::PaddingMode::NONE:
+ return KMV1::PaddingMode::NONE;
+ case V4_0::PaddingMode::RSA_OAEP:
+ return KMV1::PaddingMode::RSA_OAEP;
+ case V4_0::PaddingMode::RSA_PSS:
+ return KMV1::PaddingMode::RSA_PSS;
+ case V4_0::PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+ return KMV1::PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+ case V4_0::PaddingMode::RSA_PKCS1_1_5_SIGN:
+ return KMV1::PaddingMode::RSA_PKCS1_1_5_SIGN;
+ case V4_0::PaddingMode::PKCS7:
+ return KMV1::PaddingMode::PKCS7;
+ }
+}
+
+static V4_0::HardwareAuthenticatorType convert(KMV1::HardwareAuthenticatorType h) {
+ uint32_t result = 0;
+ uint32_t hat = static_cast<uint32_t>(h);
+ if (hat & static_cast<uint32_t>(KMV1::HardwareAuthenticatorType::PASSWORD)) {
+ result |= static_cast<uint32_t>(V4_0::HardwareAuthenticatorType::PASSWORD);
+ }
+ if (hat & static_cast<uint32_t>(KMV1::HardwareAuthenticatorType::FINGERPRINT)) {
+ result |= static_cast<uint32_t>(V4_0::HardwareAuthenticatorType::FINGERPRINT);
+ }
+ return static_cast<V4_0::HardwareAuthenticatorType>(result);
+}
+
+static KMV1::HardwareAuthenticatorType convert(V4_0::HardwareAuthenticatorType h) {
+ uint32_t result = 0;
+ if ((uint32_t)h & (uint32_t)V4_0::HardwareAuthenticatorType::PASSWORD) {
+ result |= (uint32_t)KMV1::HardwareAuthenticatorType::PASSWORD;
+ }
+ if ((uint32_t)h & (uint32_t)V4_0::HardwareAuthenticatorType::FINGERPRINT) {
+ result |= (uint32_t)KMV1::HardwareAuthenticatorType::FINGERPRINT;
+ }
+ return static_cast<KMV1::HardwareAuthenticatorType>(result);
+}
+
+static V4_0::SecurityLevel convert(KMV1::SecurityLevel s) {
+ switch (s) {
+ case KMV1::SecurityLevel::SOFTWARE:
+ return V4_0::SecurityLevel::SOFTWARE;
+ case KMV1::SecurityLevel::TRUSTED_ENVIRONMENT:
+ return V4_0::SecurityLevel::TRUSTED_ENVIRONMENT;
+ case KMV1::SecurityLevel::STRONGBOX:
+ return V4_0::SecurityLevel::STRONGBOX;
+ }
+}
+
+static KMV1::SecurityLevel convert(V4_0::SecurityLevel s) {
+ switch (s) {
+ case V4_0::SecurityLevel::SOFTWARE:
+ return KMV1::SecurityLevel::SOFTWARE;
+ case V4_0::SecurityLevel::TRUSTED_ENVIRONMENT:
+ return KMV1::SecurityLevel::TRUSTED_ENVIRONMENT;
+ case V4_0::SecurityLevel::STRONGBOX:
+ return KMV1::SecurityLevel::STRONGBOX;
+ }
+}
+
+static V4_0::KeyOrigin convert(KMV1::KeyOrigin o) {
+ switch (o) {
+ case KMV1::KeyOrigin::GENERATED:
+ return V4_0::KeyOrigin::GENERATED;
+ case KMV1::KeyOrigin::DERIVED:
+ return V4_0::KeyOrigin::DERIVED;
+ case KMV1::KeyOrigin::IMPORTED:
+ return V4_0::KeyOrigin::IMPORTED;
+ case KMV1::KeyOrigin::RESERVED:
+ return V4_0::KeyOrigin::UNKNOWN;
+ case KMV1::KeyOrigin::SECURELY_IMPORTED:
+ return V4_0::KeyOrigin::SECURELY_IMPORTED;
+ }
+}
+
+static KMV1::KeyOrigin convert(V4_0::KeyOrigin o) {
+ switch (o) {
+ case V4_0::KeyOrigin::GENERATED:
+ return KMV1::KeyOrigin::GENERATED;
+ case V4_0::KeyOrigin::DERIVED:
+ return KMV1::KeyOrigin::DERIVED;
+ case V4_0::KeyOrigin::IMPORTED:
+ return KMV1::KeyOrigin::IMPORTED;
+ case V4_0::KeyOrigin::UNKNOWN:
+ return KMV1::KeyOrigin::RESERVED;
+ case V4_0::KeyOrigin::SECURELY_IMPORTED:
+ return KMV1::KeyOrigin::SECURELY_IMPORTED;
+ }
+}
+
+static V4_0::KeyParameter convertKeyParameterToLegacy(const KMV1::KeyParameter& kp) {
+ switch (kp.tag) {
+ case KMV1::Tag::INVALID:
+ break;
+ case KMV1::Tag::PURPOSE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_PURPOSE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_PURPOSE, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::ALGORITHM:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ALGORITHM, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ALGORITHM, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::KEY_SIZE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_KEY_SIZE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_KEY_SIZE, v->get());
+ }
+ break;
+ case KMV1::Tag::BLOCK_MODE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_BLOCK_MODE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_BLOCK_MODE, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::DIGEST:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_DIGEST, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_DIGEST, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::PADDING:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_PADDING, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_PADDING, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::CALLER_NONCE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_CALLER_NONCE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_CALLER_NONCE, v->get());
+ }
+ break;
+ case KMV1::Tag::MIN_MAC_LENGTH:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_MIN_MAC_LENGTH, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_MIN_MAC_LENGTH, v->get());
+ }
+ break;
+ case KMV1::Tag::EC_CURVE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_EC_CURVE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_EC_CURVE, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::RSA_PUBLIC_EXPONENT:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_RSA_PUBLIC_EXPONENT, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_RSA_PUBLIC_EXPONENT, v->get());
+ }
+ break;
+ case KMV1::Tag::INCLUDE_UNIQUE_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_INCLUDE_UNIQUE_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_INCLUDE_UNIQUE_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::BLOB_USAGE_REQUIREMENTS:
+ // This tag has been removed. Mapped on invalid.
+ break;
+ case KMV1::Tag::BOOTLOADER_ONLY:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_BOOTLOADER_ONLY, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_BOOTLOADER_ONLY, v->get());
+ }
+ break;
+ case KMV1::Tag::ROLLBACK_RESISTANCE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ROLLBACK_RESISTANCE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ROLLBACK_RESISTANCE, v->get());
+ }
+ break;
+ case KMV1::Tag::HARDWARE_TYPE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_HARDWARE_TYPE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_HARDWARE_TYPE, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::EARLY_BOOT_ONLY:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_EARLY_BOOT_ONLY, kp)) {
+ return V4_0::makeKeyParameter(V4_1::TAG_EARLY_BOOT_ONLY, v->get());
+ }
+ break;
+ case KMV1::Tag::ACTIVE_DATETIME:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ACTIVE_DATETIME, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ACTIVE_DATETIME, v->get());
+ }
+ break;
+ case KMV1::Tag::ORIGINATION_EXPIRE_DATETIME:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ORIGINATION_EXPIRE_DATETIME, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ORIGINATION_EXPIRE_DATETIME, v->get());
+ }
+ break;
+ case KMV1::Tag::USAGE_EXPIRE_DATETIME:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_USAGE_EXPIRE_DATETIME, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_USAGE_EXPIRE_DATETIME, v->get());
+ }
+ break;
+ case KMV1::Tag::MIN_SECONDS_BETWEEN_OPS:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_MIN_SECONDS_BETWEEN_OPS, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_MIN_SECONDS_BETWEEN_OPS, v->get());
+ }
+ break;
+ case KMV1::Tag::MAX_USES_PER_BOOT:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_MAX_USES_PER_BOOT, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_MAX_USES_PER_BOOT, v->get());
+ }
+ break;
+ case KMV1::Tag::USER_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_USER_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::USER_SECURE_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_SECURE_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_USER_SECURE_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::NO_AUTH_REQUIRED:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_NO_AUTH_REQUIRED, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_NO_AUTH_REQUIRED, v->get());
+ }
+ break;
+ case KMV1::Tag::USER_AUTH_TYPE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_AUTH_TYPE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_USER_AUTH_TYPE, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::AUTH_TIMEOUT:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_AUTH_TIMEOUT, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_AUTH_TIMEOUT, v->get());
+ }
+ break;
+ case KMV1::Tag::ALLOW_WHILE_ON_BODY:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ALLOW_WHILE_ON_BODY, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ALLOW_WHILE_ON_BODY, v->get());
+ }
+ break;
+ case KMV1::Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_TRUSTED_USER_PRESENCE_REQUIRED, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_TRUSTED_USER_PRESENCE_REQUIRED, v->get());
+ }
+ break;
+ case KMV1::Tag::TRUSTED_CONFIRMATION_REQUIRED:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_TRUSTED_CONFIRMATION_REQUIRED, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_TRUSTED_CONFIRMATION_REQUIRED, v->get());
+ }
+ break;
+ case KMV1::Tag::UNLOCKED_DEVICE_REQUIRED:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_UNLOCKED_DEVICE_REQUIRED, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_UNLOCKED_DEVICE_REQUIRED, v->get());
+ }
+ break;
+ case KMV1::Tag::APPLICATION_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_APPLICATION_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_APPLICATION_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::APPLICATION_DATA:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_APPLICATION_DATA, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_APPLICATION_DATA, v->get());
+ }
+ break;
+ case KMV1::Tag::CREATION_DATETIME:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_CREATION_DATETIME, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_CREATION_DATETIME, v->get());
+ }
+ break;
+ case KMV1::Tag::ORIGIN:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ORIGIN, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ORIGIN, convert(v->get()));
+ }
+ break;
+ case KMV1::Tag::ROOT_OF_TRUST:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ROOT_OF_TRUST, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ROOT_OF_TRUST, v->get());
+ }
+ break;
+ case KMV1::Tag::OS_VERSION:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_OS_VERSION, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_OS_VERSION, v->get());
+ }
+ break;
+ case KMV1::Tag::OS_PATCHLEVEL:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_OS_PATCHLEVEL, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_OS_PATCHLEVEL, v->get());
+ }
+ break;
+ case KMV1::Tag::UNIQUE_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_UNIQUE_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_UNIQUE_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_CHALLENGE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_CHALLENGE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_CHALLENGE, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_APPLICATION_ID:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_APPLICATION_ID, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_APPLICATION_ID, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_ID_BRAND:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_BRAND, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_BRAND, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_ID_DEVICE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_DEVICE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_DEVICE, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_ID_PRODUCT:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_PRODUCT, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_PRODUCT, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_ID_SERIAL:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case KMV1::Tag::ATTESTATION_ID_IMEI:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case KMV1::Tag::ATTESTATION_ID_MEID:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case KMV1::Tag::ATTESTATION_ID_MANUFACTURER:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_MANUFACTURER, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, v->get());
+ }
+ break;
+ case KMV1::Tag::ATTESTATION_ID_MODEL:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_MODEL, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_MODEL, v->get());
+ }
+ break;
+ case KMV1::Tag::VENDOR_PATCHLEVEL:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_VENDOR_PATCHLEVEL, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_VENDOR_PATCHLEVEL, v->get());
+ }
+ break;
+ case KMV1::Tag::BOOT_PATCHLEVEL:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_BOOT_PATCHLEVEL, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_BOOT_PATCHLEVEL, v->get());
+ }
+ break;
+ case KMV1::Tag::DEVICE_UNIQUE_ATTESTATION:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_DEVICE_UNIQUE_ATTESTATION, kp)) {
+ return V4_0::makeKeyParameter(V4_1::TAG_DEVICE_UNIQUE_ATTESTATION, v->get());
+ }
+ break;
+ case KMV1::Tag::IDENTITY_CREDENTIAL_KEY:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_IDENTITY_CREDENTIAL_KEY, kp)) {
+ return V4_0::makeKeyParameter(V4_1::TAG_IDENTITY_CREDENTIAL_KEY, v->get());
+ }
+ break;
+ case KMV1::Tag::STORAGE_KEY:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_STORAGE_KEY, kp)) {
+ return V4_0::makeKeyParameter(V4_1::TAG_STORAGE_KEY, v->get());
+ }
+ break;
+ case KMV1::Tag::ASSOCIATED_DATA:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_ASSOCIATED_DATA, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_ASSOCIATED_DATA, v->get());
+ }
+ break;
+ case KMV1::Tag::NONCE:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_NONCE, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_NONCE, v->get());
+ }
+ break;
+ case KMV1::Tag::MAC_LENGTH:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_MAC_LENGTH, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_MAC_LENGTH, v->get());
+ }
+ break;
+ case KMV1::Tag::RESET_SINCE_ID_ROTATION:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_RESET_SINCE_ID_ROTATION, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_RESET_SINCE_ID_ROTATION, v->get());
+ }
+ break;
+ case KMV1::Tag::CONFIRMATION_TOKEN:
+ if (auto v = KMV1::authorizationValue(KMV1::TAG_CONFIRMATION_TOKEN, kp)) {
+ return V4_0::makeKeyParameter(V4_0::TAG_CONFIRMATION_TOKEN, v->get());
+ }
+ break;
+ case KMV1::Tag::RSA_OAEP_MGF_DIGEST:
+ // Does not exist in KM < KeyMint 1.0.
+ break;
+ }
+ return V4_0::KeyParameter{.tag = V4_0::Tag::INVALID};
+}
+
+static KMV1::KeyParameter convertKeyParameterFromLegacy(const V4_0::KeyParameter& kp) {
+ auto unwrapper = [](auto v) -> auto {
+ if (v.isOk()) {
+ return std::optional(std::reference_wrapper(v.value()));
+ } else {
+ return std::optional<decltype(std::reference_wrapper(v.value()))>{};
+ }
+ };
+ switch (kp.tag) {
+ case V4_0::Tag::INVALID:
+ break;
+ case V4_0::Tag::PURPOSE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_PURPOSE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::ALGORITHM:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ALGORITHM, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::KEY_SIZE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_KEY_SIZE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, v->get());
+ }
+ break;
+ case V4_0::Tag::BLOCK_MODE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BLOCK_MODE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::DIGEST:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_DIGEST, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_DIGEST, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::PADDING:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_PADDING, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_PADDING, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::CALLER_NONCE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CALLER_NONCE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_CALLER_NONCE, v->get());
+ }
+ break;
+ case V4_0::Tag::MIN_MAC_LENGTH:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MIN_MAC_LENGTH, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_MIN_MAC_LENGTH, v->get());
+ }
+ break;
+ case V4_0::Tag::EC_CURVE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_EC_CURVE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_EC_CURVE, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::RSA_PUBLIC_EXPONENT:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_RSA_PUBLIC_EXPONENT, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, v->get());
+ }
+ break;
+ case V4_0::Tag::INCLUDE_UNIQUE_ID:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_INCLUDE_UNIQUE_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_INCLUDE_UNIQUE_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::BLOB_USAGE_REQUIREMENTS:
+ // This tag has been removed. Mapped on invalid.
+ break;
+ case V4_0::Tag::BOOTLOADER_ONLY:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BOOTLOADER_ONLY, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_BOOTLOADER_ONLY, v->get());
+ }
+ break;
+ case V4_0::Tag::ROLLBACK_RESISTANCE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ROLLBACK_RESISTANCE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ROLLBACK_RESISTANCE, v->get());
+ }
+ break;
+ case V4_0::Tag::HARDWARE_TYPE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_HARDWARE_TYPE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_HARDWARE_TYPE, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::ACTIVE_DATETIME:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ACTIVE_DATETIME, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ACTIVE_DATETIME, v->get());
+ }
+ break;
+ case V4_0::Tag::ORIGINATION_EXPIRE_DATETIME:
+ if (auto v =
+ unwrapper(V4_0::authorizationValue(V4_0::TAG_ORIGINATION_EXPIRE_DATETIME, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ORIGINATION_EXPIRE_DATETIME, v->get());
+ }
+ break;
+ case V4_0::Tag::USAGE_EXPIRE_DATETIME:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USAGE_EXPIRE_DATETIME, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_USAGE_EXPIRE_DATETIME, v->get());
+ }
+ break;
+ case V4_0::Tag::MIN_SECONDS_BETWEEN_OPS:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MIN_SECONDS_BETWEEN_OPS, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_MIN_SECONDS_BETWEEN_OPS, v->get());
+ }
+ break;
+ case V4_0::Tag::MAX_USES_PER_BOOT:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MAX_USES_PER_BOOT, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_MAX_USES_PER_BOOT, v->get());
+ }
+ break;
+ case V4_0::Tag::USER_ID:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_USER_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::USER_SECURE_ID:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_SECURE_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_USER_SECURE_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::NO_AUTH_REQUIRED:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_NO_AUTH_REQUIRED, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, v->get());
+ }
+ break;
+ case V4_0::Tag::USER_AUTH_TYPE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_AUTH_TYPE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_USER_AUTH_TYPE, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::AUTH_TIMEOUT:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_AUTH_TIMEOUT, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_AUTH_TIMEOUT, v->get());
+ }
+ break;
+ case V4_0::Tag::ALLOW_WHILE_ON_BODY:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ALLOW_WHILE_ON_BODY, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ALLOW_WHILE_ON_BODY, v->get());
+ }
+ break;
+ case V4_0::Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+ if (auto v =
+ unwrapper(V4_0::authorizationValue(V4_0::TAG_TRUSTED_USER_PRESENCE_REQUIRED, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_TRUSTED_USER_PRESENCE_REQUIRED, v->get());
+ }
+ break;
+ case V4_0::Tag::TRUSTED_CONFIRMATION_REQUIRED:
+ if (auto v =
+ unwrapper(V4_0::authorizationValue(V4_0::TAG_TRUSTED_CONFIRMATION_REQUIRED, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_TRUSTED_CONFIRMATION_REQUIRED, v->get());
+ }
+ break;
+ case V4_0::Tag::UNLOCKED_DEVICE_REQUIRED:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_UNLOCKED_DEVICE_REQUIRED, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_UNLOCKED_DEVICE_REQUIRED, v->get());
+ }
+ break;
+ case V4_0::Tag::APPLICATION_ID:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_APPLICATION_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_APPLICATION_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::APPLICATION_DATA:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_APPLICATION_DATA, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_APPLICATION_DATA, v->get());
+ }
+ break;
+ case V4_0::Tag::CREATION_DATETIME:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CREATION_DATETIME, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_CREATION_DATETIME, v->get());
+ }
+ break;
+ case V4_0::Tag::ORIGIN:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ORIGIN, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ORIGIN, convert(v->get()));
+ }
+ break;
+ case V4_0::Tag::ROOT_OF_TRUST:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ROOT_OF_TRUST, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ROOT_OF_TRUST, v->get());
+ }
+ break;
+ case V4_0::Tag::OS_VERSION:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_OS_VERSION, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_OS_VERSION, v->get());
+ }
+ break;
+ case V4_0::Tag::OS_PATCHLEVEL:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_OS_PATCHLEVEL, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_OS_PATCHLEVEL, v->get());
+ }
+ break;
+ case V4_0::Tag::UNIQUE_ID:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_UNIQUE_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_UNIQUE_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_CHALLENGE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_CHALLENGE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_CHALLENGE, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_APPLICATION_ID:
+ if (auto v =
+ unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_APPLICATION_ID, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_APPLICATION_ID, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_ID_BRAND:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_BRAND, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_BRAND, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_ID_DEVICE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_DEVICE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_DEVICE, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_ID_PRODUCT:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_PRODUCT, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_PRODUCT, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_ID_SERIAL:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case V4_0::Tag::ATTESTATION_ID_IMEI:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case V4_0::Tag::ATTESTATION_ID_MEID:
+ // TODO This tag is missing from 4.0 keymaster_tags.h
+ break;
+ case V4_0::Tag::ATTESTATION_ID_MANUFACTURER:
+ if (auto v =
+ unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_MANUFACTURER, v->get());
+ }
+ break;
+ case V4_0::Tag::ATTESTATION_ID_MODEL:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_MODEL, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_MODEL, v->get());
+ }
+ break;
+ case V4_0::Tag::VENDOR_PATCHLEVEL:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_VENDOR_PATCHLEVEL, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_VENDOR_PATCHLEVEL, v->get());
+ }
+ break;
+ case V4_0::Tag::BOOT_PATCHLEVEL:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BOOT_PATCHLEVEL, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_BOOT_PATCHLEVEL, v->get());
+ }
+ break;
+ case V4_0::Tag::ASSOCIATED_DATA:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ASSOCIATED_DATA, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_ASSOCIATED_DATA, v->get());
+ }
+ break;
+ case V4_0::Tag::NONCE:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_NONCE, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_NONCE, v->get());
+ }
+ break;
+ case V4_0::Tag::MAC_LENGTH:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MAC_LENGTH, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_MAC_LENGTH, v->get());
+ }
+ break;
+ case V4_0::Tag::RESET_SINCE_ID_ROTATION:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_RESET_SINCE_ID_ROTATION, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_RESET_SINCE_ID_ROTATION, v->get());
+ }
+ break;
+ case V4_0::Tag::CONFIRMATION_TOKEN:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CONFIRMATION_TOKEN, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_CONFIRMATION_TOKEN, v->get());
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (static_cast<V4_1::Tag>(kp.tag)) {
+ case V4_1::Tag::EARLY_BOOT_ONLY:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_EARLY_BOOT_ONLY, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_EARLY_BOOT_ONLY, v->get());
+ }
+ break;
+ case V4_1::Tag::DEVICE_UNIQUE_ATTESTATION:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_DEVICE_UNIQUE_ATTESTATION, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_DEVICE_UNIQUE_ATTESTATION, v->get());
+ }
+ break;
+ case V4_1::Tag::IDENTITY_CREDENTIAL_KEY:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_IDENTITY_CREDENTIAL_KEY, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_IDENTITY_CREDENTIAL_KEY, v->get());
+ }
+ break;
+ case V4_1::Tag::STORAGE_KEY:
+ if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_STORAGE_KEY, kp))) {
+ return KMV1::makeKeyParameter(KMV1::TAG_STORAGE_KEY, v->get());
+ }
+ break;
+ default:
+ break;
+ }
+
+ return KMV1::makeKeyParameter(KMV1::TAG_INVALID);
+}
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index b6a6baf..36f1303 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -32,8 +32,8 @@
Certificate::Certificate, Digest::Digest, ErrorCode::ErrorCode,
HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
- KeyParameterArray::KeyParameterArray, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
- SecurityLevel::SecurityLevel, Tag::Tag,
+ KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue,
+ KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
};
use android_hardware_security_keymint::binder;
use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
@@ -87,39 +87,40 @@
fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
let mut kps = vec![
- KeyParameter { tag: Tag::ALGORITHM, integer: Algorithm::RSA.0, ..Default::default() },
- KeyParameter { tag: Tag::KEY_SIZE, integer: 2048, ..Default::default() },
+ KeyParameter {
+ tag: Tag::ALGORITHM,
+ value: KeyParameterValue::Algorithm(Algorithm::RSA),
+ },
+ KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
KeyParameter {
tag: Tag::RSA_PUBLIC_EXPONENT,
- longInteger: 65537,
- ..Default::default()
+ value: KeyParameterValue::LongInteger(65537),
},
- KeyParameter { tag: Tag::DIGEST, integer: Digest::SHA_2_256.0, ..Default::default() },
+ KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
KeyParameter {
tag: Tag::PADDING,
- integer: PaddingMode::RSA_PSS.0,
- ..Default::default()
+ value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
},
- KeyParameter { tag: Tag::NO_AUTH_REQUIRED, boolValue: true, ..Default::default() },
- KeyParameter { tag: Tag::PURPOSE, integer: KeyPurpose::SIGN.0, ..Default::default() },
+ KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
+ KeyParameter {
+ tag: Tag::PURPOSE,
+ value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
+ },
];
if encrypt {
kps.push(KeyParameter {
tag: Tag::PURPOSE,
- integer: KeyPurpose::ENCRYPT.0,
- ..Default::default()
+ value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
});
}
if attest {
kps.push(KeyParameter {
tag: Tag::ATTESTATION_CHALLENGE,
- blob: vec![42; 8],
- ..Default::default()
+ value: KeyParameterValue::Blob(vec![42; 8]),
});
kps.push(KeyParameter {
tag: Tag::ATTESTATION_APPLICATION_ID,
- blob: vec![42; 8],
- ..Default::default()
+ value: KeyParameterValue::Blob(vec![42; 8]),
});
}
let (blob, _, cert_chain) = generate_key(legacy, kps);
@@ -153,8 +154,10 @@
#[test]
fn test_import_key() {
let legacy = get_device();
- let kps =
- [KeyParameter { tag: Tag::ALGORITHM, integer: Algorithm::AES.0, ..Default::default() }];
+ let kps = [KeyParameter {
+ tag: Tag::ALGORITHM,
+ value: KeyParameterValue::Algorithm(Algorithm::AES),
+ }];
let kf = KeyFormat::RAW;
let kd = [0; 16];
let mut blob = ByteArray { data: vec![] };
@@ -212,20 +215,27 @@
fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
let kps = vec![
- KeyParameter { tag: Tag::ALGORITHM, integer: Algorithm::AES.0, ..Default::default() },
- KeyParameter { tag: Tag::KEY_SIZE, integer: 128, ..Default::default() },
- KeyParameter { tag: Tag::BLOCK_MODE, integer: BlockMode::CBC.0, ..Default::default() },
- KeyParameter { tag: Tag::PADDING, integer: PaddingMode::NONE.0, ..Default::default() },
- KeyParameter { tag: Tag::NO_AUTH_REQUIRED, boolValue: true, ..Default::default() },
+ KeyParameter {
+ tag: Tag::ALGORITHM,
+ value: KeyParameterValue::Algorithm(Algorithm::AES),
+ },
+ KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
+ KeyParameter {
+ tag: Tag::BLOCK_MODE,
+ value: KeyParameterValue::BlockMode(BlockMode::CBC),
+ },
+ KeyParameter {
+ tag: Tag::PADDING,
+ value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
+ },
+ KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
KeyParameter {
tag: Tag::PURPOSE,
- integer: KeyPurpose::ENCRYPT.0,
- ..Default::default()
+ value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
},
KeyParameter {
tag: Tag::PURPOSE,
- integer: KeyPurpose::DECRYPT.0,
- ..Default::default()
+ value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
},
];
let (blob, _, cert_chain) = generate_key(legacy, kps);
@@ -240,8 +250,14 @@
extra_params: Option<Vec<KeyParameter>>,
) -> BeginResult {
let mut kps = vec![
- KeyParameter { tag: Tag::BLOCK_MODE, integer: BlockMode::CBC.0, ..Default::default() },
- KeyParameter { tag: Tag::PADDING, integer: PaddingMode::NONE.0, ..Default::default() },
+ KeyParameter {
+ tag: Tag::BLOCK_MODE,
+ value: KeyParameterValue::BlockMode(BlockMode::CBC),
+ },
+ KeyParameter {
+ tag: Tag::PADDING,
+ value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
+ },
];
if let Some(mut extras) = extra_params {
kps.append(&mut extras);
@@ -273,8 +289,7 @@
let params = KeyParameterArray {
params: vec![KeyParameter {
tag: Tag::ASSOCIATED_DATA,
- blob: b"foobar".to_vec(),
- ..Default::default()
+ value: KeyParameterValue::Blob(b"foobar".to_vec()),
}],
};
let message = [42; 128];
diff --git a/keystore2/src/km_compat/parameter_conversion_test.cpp b/keystore2/src/km_compat/parameter_conversion_test.cpp
new file mode 100644
index 0000000..41be067
--- /dev/null
+++ b/keystore2/src/km_compat/parameter_conversion_test.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include "km_compat_type_conversion.h"
+
+#define TEST_ENUM_CONVERSION(type, variant) \
+ ASSERT_EQ(KMV1::type::variant, convert(V4_0::type::variant)); \
+ ASSERT_EQ(V4_0::type::variant, convert(KMV1::type::variant))
+
+TEST(KmCompatTypeConversionTest, testEnumCoversion) {
+ TEST_ENUM_CONVERSION(KeyPurpose, ENCRYPT);
+ TEST_ENUM_CONVERSION(KeyPurpose, DECRYPT);
+ TEST_ENUM_CONVERSION(KeyPurpose, SIGN);
+ TEST_ENUM_CONVERSION(KeyPurpose, VERIFY);
+ TEST_ENUM_CONVERSION(KeyPurpose, WRAP_KEY);
+ TEST_ENUM_CONVERSION(Algorithm, RSA);
+ TEST_ENUM_CONVERSION(Algorithm, EC);
+ TEST_ENUM_CONVERSION(Algorithm, AES);
+ TEST_ENUM_CONVERSION(Algorithm, TRIPLE_DES);
+ TEST_ENUM_CONVERSION(Algorithm, HMAC);
+ TEST_ENUM_CONVERSION(Digest, NONE);
+ TEST_ENUM_CONVERSION(Digest, MD5);
+ TEST_ENUM_CONVERSION(Digest, SHA1);
+ TEST_ENUM_CONVERSION(Digest, SHA_2_224);
+ TEST_ENUM_CONVERSION(Digest, SHA_2_256);
+ TEST_ENUM_CONVERSION(Digest, SHA_2_384);
+ TEST_ENUM_CONVERSION(Digest, SHA_2_512);
+ TEST_ENUM_CONVERSION(EcCurve, P_224);
+ TEST_ENUM_CONVERSION(EcCurve, P_256);
+ TEST_ENUM_CONVERSION(EcCurve, P_384);
+ TEST_ENUM_CONVERSION(EcCurve, P_521);
+ TEST_ENUM_CONVERSION(BlockMode, ECB);
+ TEST_ENUM_CONVERSION(BlockMode, CBC);
+ TEST_ENUM_CONVERSION(BlockMode, CTR);
+ TEST_ENUM_CONVERSION(BlockMode, GCM);
+ TEST_ENUM_CONVERSION(PaddingMode, NONE);
+ TEST_ENUM_CONVERSION(PaddingMode, RSA_OAEP);
+ TEST_ENUM_CONVERSION(PaddingMode, RSA_PSS);
+ TEST_ENUM_CONVERSION(PaddingMode, RSA_PKCS1_1_5_ENCRYPT);
+ TEST_ENUM_CONVERSION(PaddingMode, RSA_PKCS1_1_5_SIGN);
+ TEST_ENUM_CONVERSION(PaddingMode, PKCS7);
+ TEST_ENUM_CONVERSION(HardwareAuthenticatorType, PASSWORD);
+ TEST_ENUM_CONVERSION(HardwareAuthenticatorType, FINGERPRINT);
+ TEST_ENUM_CONVERSION(SecurityLevel, SOFTWARE);
+ TEST_ENUM_CONVERSION(SecurityLevel, TRUSTED_ENVIRONMENT);
+ TEST_ENUM_CONVERSION(SecurityLevel, STRONGBOX);
+ TEST_ENUM_CONVERSION(KeyOrigin, GENERATED);
+ TEST_ENUM_CONVERSION(KeyOrigin, DERIVED);
+ TEST_ENUM_CONVERSION(KeyOrigin, IMPORTED);
+ TEST_ENUM_CONVERSION(KeyOrigin, GENERATED);
+ TEST_ENUM_CONVERSION(KeyOrigin, SECURELY_IMPORTED);
+
+ // RESERVED and UNKNOWN correspond but changed their names.
+ ASSERT_EQ(KMV1::KeyOrigin::RESERVED, convert(V4_0::KeyOrigin::UNKNOWN));
+ ASSERT_EQ(V4_0::KeyOrigin::UNKNOWN, convert(KMV1::KeyOrigin::RESERVED));
+}
+
+#define TEST_KEY_PARAMETER_CONVERSION_V4_0(tag) \
+ do { \
+ auto kmv1_param = KMV1::makeKeyParameter( \
+ KMV1::tag, KMV1::TypedTag2ValueType<decltype(KMV1::tag)>::type{}); \
+ auto legacy_param = V4_0::makeKeyParameter( \
+ V4_0::tag, V4_0::TypedTag2ValueType<decltype(V4_0::tag)>::type{}); \
+ ASSERT_EQ(legacy_param, convertKeyParameterToLegacy(kmv1_param)); \
+ ASSERT_EQ(kmv1_param, convertKeyParameterFromLegacy(legacy_param)); \
+ } while (false)
+
+#define TEST_KEY_PARAMETER_CONVERSION_V4_1(tag) \
+ do { \
+ auto kmv1_param = KMV1::makeKeyParameter( \
+ KMV1::tag, KMV1::TypedTag2ValueType<decltype(KMV1::tag)>::type{}); \
+ auto legacy_param = V4_0::makeKeyParameter( \
+ V4_1::tag, V4_0::TypedTag2ValueType<decltype(V4_1::tag)>::type{}); \
+ ASSERT_EQ(legacy_param, convertKeyParameterToLegacy(kmv1_param)); \
+ ASSERT_EQ(kmv1_param, convertKeyParameterFromLegacy(legacy_param)); \
+ } while (false)
+
+TEST(KmCompatTypeConversionTest, testKeyParameterConversion) {
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ACTIVE_DATETIME);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ALGORITHM);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ALLOW_WHILE_ON_BODY);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_APPLICATION_DATA);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_APPLICATION_ID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ASSOCIATED_DATA);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_APPLICATION_ID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_CHALLENGE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_BRAND);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_DEVICE);
+ // TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_IMEI);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MANUFACTURER);
+ // TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MEID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_PRODUCT);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MODEL);
+ // TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_SERIAL);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_AUTH_TIMEOUT);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BLOCK_MODE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BOOTLOADER_ONLY);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BOOT_PATCHLEVEL);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CALLER_NONCE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CONFIRMATION_TOKEN);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CREATION_DATETIME);
+ TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_DEVICE_UNIQUE_ATTESTATION);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_DIGEST);
+ TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_EARLY_BOOT_ONLY);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_EC_CURVE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_HARDWARE_TYPE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_IDENTITY_CREDENTIAL_KEY);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_INCLUDE_UNIQUE_ID);
+ // TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_INVALID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_KEY_SIZE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MAC_LENGTH);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MAX_USES_PER_BOOT);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MIN_MAC_LENGTH);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MIN_SECONDS_BETWEEN_OPS);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_NONCE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_NO_AUTH_REQUIRED);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ORIGIN);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ORIGINATION_EXPIRE_DATETIME);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_OS_PATCHLEVEL);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_OS_VERSION);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_PADDING);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_PURPOSE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_RESET_SINCE_ID_ROTATION);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ROLLBACK_RESISTANCE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ROOT_OF_TRUST);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_RSA_PUBLIC_EXPONENT);
+ TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_STORAGE_KEY);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_TRUSTED_CONFIRMATION_REQUIRED);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_TRUSTED_USER_PRESENCE_REQUIRED);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_UNIQUE_ID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_UNLOCKED_DEVICE_REQUIRED);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USAGE_EXPIRE_DATETIME);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_AUTH_TYPE);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_ID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_SECURE_ID);
+ TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_VENDOR_PATCHLEVEL);
+}