Merge "Add new SecurityLevel::KEYSTORE"
diff --git a/identity/Android.bp b/identity/Android.bp
index dd61930..e6d77c8 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -39,8 +39,8 @@
"libkeystore-attestation-application-id",
],
static_libs: [
- "android.hardware.identity-unstable-cpp",
- "android.hardware.keymaster-unstable-cpp",
+ "android.hardware.identity-V3-cpp",
+ "android.hardware.keymaster-V3-cpp",
"libcppbor",
]
}
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 785847d..4e12c64 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -617,6 +617,11 @@
perboot_path_str.push_str(&perboot_path.to_string_lossy());
let conn = Self::make_connection(&persistent_path_str, &perboot_path_str)?;
+ conn.busy_handler(Some(|_| {
+ std::thread::sleep(std::time::Duration::from_micros(50));
+ true
+ }))
+ .context("In KeystoreDB::new: Failed to set busy handler.")?;
Self::init_tables(&conn)?;
Ok(Self { conn })
diff --git a/keystore2/src/km_compat/Android.bp b/keystore2/src/km_compat/Android.bp
index 126aeff..2180935 100644
--- a/keystore2/src/km_compat/Android.bp
+++ b/keystore2/src/km_compat/Android.bp
@@ -48,11 +48,11 @@
"android.hardware.keymaster@3.0",
"android.hardware.keymaster@4.0",
"android.hardware.keymaster@4.1",
- "android.hardware.security.keymint-unstable-ndk_platform",
- "android.hardware.security.secureclock-unstable-ndk_platform",
- "android.hardware.security.sharedsecret-unstable-ndk_platform",
+ "android.hardware.security.keymint-V1-ndk_platform",
+ "android.hardware.security.secureclock-V1-ndk_platform",
+ "android.hardware.security.sharedsecret-V1-ndk_platform",
"android.security.compat-ndk_platform",
- "android.system.keystore2-ndk_platform",
+ "android.system.keystore2-V1-ndk_platform",
"libbase",
"libbinder_ndk",
"libcrypto",
@@ -68,9 +68,9 @@
name: "libkm_compat_service",
srcs: ["km_compat_service.cpp"],
shared_libs: [
- "android.hardware.security.keymint-unstable-ndk_platform",
- "android.hardware.security.secureclock-unstable-ndk_platform",
- "android.hardware.security.sharedsecret-unstable-ndk_platform",
+ "android.hardware.security.keymint-V1-ndk_platform",
+ "android.hardware.security.secureclock-V1-ndk_platform",
+ "android.hardware.security.sharedsecret-V1-ndk_platform",
"android.security.compat-ndk_platform",
"libbinder_ndk",
"libcrypto",
@@ -97,11 +97,11 @@
"android.hardware.keymaster@3.0",
"android.hardware.keymaster@4.0",
"android.hardware.keymaster@4.1",
- "android.hardware.security.keymint-unstable-ndk_platform",
- "android.hardware.security.secureclock-unstable-ndk_platform",
- "android.hardware.security.sharedsecret-unstable-ndk_platform",
+ "android.hardware.security.keymint-V1-ndk_platform",
+ "android.hardware.security.secureclock-V1-ndk_platform",
+ "android.hardware.security.sharedsecret-V1-ndk_platform",
"android.security.compat-ndk_platform",
- "android.system.keystore2-ndk_platform",
+ "android.system.keystore2-V1-ndk_platform",
"libbase",
"libbinder_ndk",
"libcrypto",
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 9383c09..601baf1 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -52,19 +52,23 @@
// Utility functions
-// Converts a V4 error code into a ScopedAStatus
-ScopedAStatus convertErrorCode(V4_0_ErrorCode result) {
- if (result == V4_0_ErrorCode::OK) {
+ScopedAStatus convertErrorCode(KMV1::ErrorCode result) {
+ if (result == KMV1::ErrorCode::OK) {
return ScopedAStatus::ok();
}
return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
}
-static V4_0_ErrorCode toErrorCode(const ScopedAStatus& status) {
+// Converts a V4 error code into a ScopedAStatus
+ScopedAStatus convertErrorCode(V4_0_ErrorCode result) {
+ return convertErrorCode(convert(result));
+}
+
+static KMV1::ErrorCode toErrorCode(const ScopedAStatus& status) {
if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
- return static_cast<V4_0_ErrorCode>(status.getServiceSpecificError());
+ return static_cast<KMV1::ErrorCode>(status.getServiceSpecificError());
} else {
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
}
@@ -183,25 +187,27 @@
_aidl_return->keyMintAuthorName = keymasterAuthorName;
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return ScopedAStatus::ok();
}
ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector<uint8_t>& in_data) {
- V4_0_ErrorCode errorCode = mDevice->addRngEntropy(in_data);
- return convertErrorCode(errorCode);
+ auto result = mDevice->addRngEntropy(in_data);
+ if (!result.isOk()) {
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+ }
+ return convertErrorCode(result);
}
ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& in_keyParams,
KeyCreationResult* out_creationResult) {
auto legacyKeyParams = convertKeyParametersToLegacy(in_keyParams);
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->generateKey(
legacyKeyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) {
- errorCode = error;
+ errorCode = convert(error);
out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics);
@@ -210,12 +216,12 @@
return ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
}
- if (errorCode == V4_0_ErrorCode::OK) {
+ if (errorCode == KMV1::ErrorCode::OK) {
auto cert = getCertificate(in_keyParams, out_creationResult->keyBlob);
- if (std::holds_alternative<V4_0_ErrorCode>(cert)) {
- auto code = std::get<V4_0_ErrorCode>(cert);
+ if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
+ auto code = std::get<KMV1::ErrorCode>(cert);
// We return OK in successful cases that do not generate a certificate.
- if (code != V4_0_ErrorCode::OK) {
+ if (code != KMV1::ErrorCode::OK) {
errorCode = code;
deleteKey(out_creationResult->keyBlob);
}
@@ -232,26 +238,25 @@
KeyCreationResult* out_creationResult) {
auto legacyKeyParams = convertKeyParametersToLegacy(in_inKeyParams);
auto legacyKeyFormat = convertKeyFormatToLegacy(in_inKeyFormat);
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->importKey(legacyKeyParams, legacyKeyFormat, in_inKeyData,
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) {
- errorCode = error;
+ errorCode = convert(error);
out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy(
securityLevel_, keyCharacteristics);
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
- if (errorCode == V4_0_ErrorCode::OK) {
+ if (errorCode == KMV1::ErrorCode::OK) {
auto cert = getCertificate(in_inKeyParams, out_creationResult->keyBlob);
- if (std::holds_alternative<V4_0_ErrorCode>(cert)) {
- auto code = std::get<V4_0_ErrorCode>(cert);
+ if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
+ auto code = std::get<KMV1::ErrorCode>(cert);
// We return OK in successful cases that do not generate a certificate.
- if (code != V4_0_ErrorCode::OK) {
+ if (code != KMV1::ErrorCode::OK) {
errorCode = code;
deleteKey(out_creationResult->keyBlob);
}
@@ -268,20 +273,19 @@
const std::vector<KeyParameter>& in_inUnwrappingParams, int64_t in_inPasswordSid,
int64_t in_inBiometricSid, KeyCreationResult* out_creationResult) {
auto legacyUnwrappingParams = convertKeyParametersToLegacy(in_inUnwrappingParams);
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->importWrappedKey(
in_inWrappedKeyData, in_inWrappingKeyBlob, in_inMaskingKey, legacyUnwrappingParams,
in_inPasswordSid, in_inBiometricSid,
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) {
- errorCode = error;
+ errorCode = convert(error);
out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics);
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(errorCode);
}
@@ -298,20 +302,25 @@
*_aidl_return = upgradedKeyBlob;
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(errorCode);
}
ScopedAStatus KeyMintDevice::deleteKey(const std::vector<uint8_t>& in_inKeyBlob) {
- V4_0_ErrorCode errorCode = mDevice->deleteKey(in_inKeyBlob);
- return convertErrorCode(errorCode);
+ auto result = mDevice->deleteKey(in_inKeyBlob);
+ if (!result.isOk()) {
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+ }
+ return convertErrorCode(result);
}
ScopedAStatus KeyMintDevice::deleteAllKeys() {
- V4_0_ErrorCode errorCode = mDevice->deleteAllKeys();
- return convertErrorCode(errorCode);
+ auto result = mDevice->deleteAllKeys();
+ if (!result.isOk()) {
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+ }
+ return convertErrorCode(result);
}
// We're not implementing this.
@@ -332,24 +341,21 @@
static_cast<::android::hardware::keymaster::V4_0::KeyPurpose>(in_inPurpose);
auto legacyParams = convertKeyParametersToLegacy(in_inParams);
auto legacyAuthToken = convertAuthTokenToLegacy(in_inAuthToken);
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->begin(
legacyPurpose, in_inKeyBlob, legacyParams, legacyAuthToken,
[&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
uint64_t operationHandle) {
- errorCode = error;
- _aidl_return->challenge = operationHandle; // TODO: Is this right?
+ errorCode = convert(error);
+ _aidl_return->challenge = operationHandle;
_aidl_return->params = convertKeyParametersFromLegacy(outParams);
_aidl_return->operation = ndk::SharedRefBase::make<KeyMintOperation>(
mDevice, operationHandle, &mOperationSlots, error == V4_0_ErrorCode::OK);
});
if (!result.isOk()) {
- // TODO: In this case we're guaranteed that _aidl_return was not initialized, right?
- mOperationSlots.freeSlot();
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != V4_0_ErrorCode::OK) {
+ if (errorCode != KMV1::ErrorCode::OK) {
mOperationSlots.freeSlot();
}
return convertErrorCode(errorCode);
@@ -375,12 +381,12 @@
if (in_inTimeStampToken.has_value()) {
verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
}
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->update(
mOperationHandle, legacyParams, input, authToken, verificationToken,
[&](V4_0_ErrorCode error, uint32_t inputConsumed,
const hidl_vec<V4_0_KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
- errorCode = error;
+ errorCode = convert(error);
out_outParams->emplace();
out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
out_output->emplace();
@@ -388,11 +394,9 @@
*_aidl_return = inputConsumed;
});
if (!result.isOk()) {
- mOperationSlot.freeSlot();
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != V4_0_ErrorCode::OK) {
+ if (errorCode != KMV1::ErrorCode::OK) {
mOperationSlot.freeSlot();
}
return convertErrorCode(errorCode);
@@ -405,7 +409,7 @@
const std::optional<TimeStampToken>& in_inTimeStampToken,
std::optional<KeyParameterArray>* out_outParams,
std::vector<uint8_t>* _aidl_return) {
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
std::vector<V4_0_KeyParameter> legacyParams;
if (in_inParams.has_value()) {
legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
@@ -424,23 +428,25 @@
mOperationHandle, legacyParams, input, signature, authToken, verificationToken,
[&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
const hidl_vec<uint8_t>& output) {
- errorCode = error;
+ errorCode = convert(error);
out_outParams->emplace();
out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
*_aidl_return = output;
});
mOperationSlot.freeSlot();
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
return convertErrorCode(errorCode);
}
ScopedAStatus KeyMintOperation::abort() {
- V4_0_ErrorCode errorCode = mDevice->abort(mOperationHandle);
+ auto result = mDevice->abort(mOperationHandle);
mOperationSlot.freeSlot();
- return convertErrorCode(errorCode);
+ if (!result.isOk()) {
+ return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+ }
+ return convertErrorCode(result);
}
KeyMintOperation::~KeyMintOperation() {
@@ -455,18 +461,17 @@
// SecureClock implementation
ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToken* _aidl_return) {
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->verifyAuthorization(
in_challenge, {}, V4_0_HardwareAuthToken(),
[&](V4_0_ErrorCode error, const V4_0_VerificationToken& token) {
- errorCode = error;
+ errorCode = convert(error);
_aidl_return->challenge = token.challenge;
_aidl_return->timestamp.milliSeconds = token.timestamp;
_aidl_return->mac = token.mac;
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
return convertErrorCode(errorCode);
}
@@ -474,17 +479,16 @@
// SharedSecret implementation
ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _aidl_return) {
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto result = mDevice->getHmacSharingParameters(
[&](V4_0_ErrorCode error, const V4_0_HmacSharingParameters& params) {
- errorCode = error;
+ errorCode = convert(error);
_aidl_return->seed = params.seed;
std::copy(params.nonce.data(), params.nonce.data() + params.nonce.elementCount(),
std::back_inserter(_aidl_return->nonce));
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
return convertErrorCode(errorCode);
}
@@ -492,16 +496,15 @@
ScopedAStatus
SharedSecret::computeSharedSecret(const std::vector<SharedSecretParameters>& in_params,
std::vector<uint8_t>* _aidl_return) {
- V4_0_ErrorCode errorCode;
+ KMV1::ErrorCode errorCode;
auto legacyParams = convertSharedSecretParametersToLegacy(in_params);
auto result = mDevice->computeSharedHmac(
legacyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& sharingCheck) {
- errorCode = error;
+ errorCode = convert(error);
*_aidl_return = sharingCheck;
});
if (!result.isOk()) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
+ errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
}
return convertErrorCode(errorCode);
}
@@ -545,12 +548,12 @@
return *bestSoFar;
}
-static std::variant<keystore::X509_Ptr, V4_0_ErrorCode>
+static std::variant<keystore::X509_Ptr, KMV1::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;
+ KMV1::ErrorCode errorCode;
std::vector<uint8_t> key;
static std::vector<uint8_t> empty_vector;
auto unwrapBlob = [&](auto b) -> const std::vector<uint8_t>& {
@@ -563,13 +566,13 @@
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;
+ errorCode = convert(error);
key = keyMaterial;
});
if (!result.isOk()) {
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != V4_0_ErrorCode::OK) {
+ if (errorCode != KMV1::ErrorCode::OK) {
return errorCode;
}
// Get pkey for makeCert.
@@ -594,12 +597,12 @@
std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */);
if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) {
LOG(ERROR) << __func__ << ": Failed to make certificate";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
return std::move(std::get<keystore::X509_Ptr>(certOrError));
}
-static std::variant<keystore::Algo, V4_0_ErrorCode> getKeystoreAlgorithm(Algorithm algorithm) {
+static std::variant<keystore::Algo, KMV1::ErrorCode> getKeystoreAlgorithm(Algorithm algorithm) {
switch (algorithm) {
case Algorithm::RSA:
return keystore::Algo::RSA;
@@ -607,11 +610,11 @@
return keystore::Algo::ECDSA;
default:
LOG(ERROR) << __func__ << ": This should not be called with symmetric algorithm.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
}
-static std::variant<keystore::Padding, V4_0_ErrorCode> getKeystorePadding(PaddingMode padding) {
+static std::variant<keystore::Padding, KMV1::ErrorCode> getKeystorePadding(PaddingMode padding) {
switch (padding) {
case PaddingMode::RSA_PKCS1_1_5_SIGN:
return keystore::Padding::PKCS1_5;
@@ -622,7 +625,7 @@
}
}
-static std::variant<keystore::Digest, V4_0_ErrorCode> getKeystoreDigest(Digest digest) {
+static std::variant<keystore::Digest, KMV1::ErrorCode> getKeystoreDigest(Digest digest) {
switch (digest) {
case Digest::SHA1:
return keystore::Digest::SHA1;
@@ -637,36 +640,36 @@
return keystore::Digest::SHA512;
default:
LOG(ERROR) << __func__ << ": Unknown digest.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
}
-std::optional<V4_0_ErrorCode>
+std::optional<KMV1::ErrorCode>
KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob, X509* cert) {
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);
+ if (std::holds_alternative<KMV1::ErrorCode>(algoOrError)) {
+ return std::get<KMV1::ErrorCode>(algoOrError);
}
auto algo = std::get<keystore::Algo>(algoOrError);
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);
+ if (std::holds_alternative<KMV1::ErrorCode>(paddingOrError)) {
+ return std::get<KMV1::ErrorCode>(paddingOrError);
}
auto padding = std::get<keystore::Padding>(paddingOrError);
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)) {
- return std::get<V4_0_ErrorCode>(digestOrError);
+ if (std::holds_alternative<KMV1::ErrorCode>(digestOrError)) {
+ return std::get<KMV1::ErrorCode>(digestOrError);
}
auto digest = std::get<keystore::Digest>(digestOrError);
- V4_0_ErrorCode errorCode = V4_0_ErrorCode::OK;
+ KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
auto error = keystore::signCertWith(
&*cert,
[&](const uint8_t* data, size_t len) {
@@ -703,40 +706,40 @@
if (error) {
LOG(ERROR) << __func__
<< ": signCertWith failed. (Callback diagnosed: " << toString(errorCode) << ")";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != V4_0_ErrorCode::OK) {
+ if (errorCode != KMV1::ErrorCode::OK) {
return errorCode;
}
return std::nullopt;
}
-std::variant<std::vector<Certificate>, V4_0_ErrorCode>
+std::variant<std::vector<Certificate>, KMV1::ErrorCode>
KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob) {
// There are no certificates for symmetric keys.
auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
if (!algorithm) {
LOG(ERROR) << __func__ << ": Unable to determine key algorithm.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
switch (*algorithm) {
case Algorithm::RSA:
case Algorithm::EC:
break;
default:
- return V4_0_ErrorCode::OK;
+ return KMV1::ErrorCode::OK;
}
// If attestation was requested, call and use attestKey.
if (containsParam(keyParams, KMV1::TAG_ATTESTATION_CHALLENGE)) {
auto legacyParams = convertKeyParametersToLegacy(keyParams);
std::vector<Certificate> certs;
- V4_0_ErrorCode errorCode = V4_0_ErrorCode::OK;
+ KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
auto result = mDevice->attestKey(
keyBlob, legacyParams,
- [&](V4_0_ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
- errorCode = error;
+ [&](V4_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+ errorCode = convert(error);
for (const auto& cert : certChain) {
Certificate certificate;
certificate.encodedCertificate = cert;
@@ -745,9 +748,9 @@
});
if (!result.isOk()) {
LOG(ERROR) << __func__ << ": Call to attestKey failed.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
- if (errorCode != V4_0_ErrorCode::OK) {
+ if (errorCode != KMV1::ErrorCode::OK) {
return errorCode;
}
return certs;
@@ -755,8 +758,8 @@
// makeCert
auto certOrError = makeCert(mDevice, keyParams, keyBlob);
- if (std::holds_alternative<V4_0_ErrorCode>(certOrError)) {
- return std::get<V4_0_ErrorCode>(certOrError);
+ if (std::holds_alternative<KMV1::ErrorCode>(certOrError)) {
+ return std::get<KMV1::ErrorCode>(certOrError);
}
auto cert = std::move(std::get<keystore::X509_Ptr>(certOrError));
@@ -764,7 +767,7 @@
auto error = keystore::setIssuer(&*cert, &*cert, false);
if (error) {
LOG(ERROR) << __func__ << ": Set issuer failed.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
// Signing
@@ -789,7 +792,7 @@
error = keystore::signCert(&*cert, pkey_ptr);
if (error) {
LOG(ERROR) << __func__ << ": signCert failed.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
}
@@ -797,7 +800,7 @@
auto encodedCertOrError = keystore::encodeCert(&*cert);
if (std::holds_alternative<keystore::CertUtilsError>(encodedCertOrError)) {
LOG(ERROR) << __func__ << ": encodeCert failed.";
- return V4_0_ErrorCode::UNKNOWN_ERROR;
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
}
Certificate certificate{.encodedCertificate =
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 481481a..5637b58 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -18,6 +18,7 @@
#include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h>
#include <aidl/android/hardware/security/keymint/BnKeyMintOperation.h>
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <aidl/android/hardware/security/secureclock/BnSecureClock.h>
#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h>
#include <aidl/android/security/compat/BnKeystoreCompatService.h>
@@ -41,6 +42,7 @@
using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel;
using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
using ::aidl::android::hardware::security::keymint::IKeyMintDevice;
+using KMV1_ErrorCode = ::aidl::android::hardware::security::keymint::ErrorCode;
using ::aidl::android::hardware::security::secureclock::ISecureClock;
using ::aidl::android::hardware::security::secureclock::TimeStampToken;
using ::aidl::android::hardware::security::sharedsecret::ISharedSecret;
@@ -112,13 +114,13 @@
// These are public to allow testing code to use them directly.
// This class should not be used publicly anyway.
- std::variant<std::vector<Certificate>, V4_0_ErrorCode>
+ std::variant<std::vector<Certificate>, KMV1_ErrorCode>
getCertificate(const std::vector<KeyParameter>& keyParams, const std::vector<uint8_t>& keyBlob);
void setNumFreeSlots(uint8_t numFreeSlots);
private:
- std::optional<V4_0_ErrorCode> signCertificate(const std::vector<KeyParameter>& keyParams,
+ std::optional<KMV1_ErrorCode> signCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob, X509* cert);
KeyMintSecurityLevel securityLevel_;
};
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
index c0e872b..5fdca91 100644
--- a/keystore2/src/km_compat/km_compat_type_conversion.h
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -16,6 +16,7 @@
#pragma once
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <keymasterV4_1/keymaster_tags.h>
#include <keymint_support/keymint_tags.h>
@@ -23,6 +24,159 @@
namespace V4_1 = ::android::hardware::keymaster::V4_1;
namespace KMV1 = ::aidl::android::hardware::security::keymint;
+static KMV1::ErrorCode convert(V4_0::ErrorCode error) {
+ switch (error) {
+ case V4_0::ErrorCode::OK:
+ return KMV1::ErrorCode::OK;
+ case V4_0::ErrorCode::ROOT_OF_TRUST_ALREADY_SET:
+ return KMV1::ErrorCode::ROOT_OF_TRUST_ALREADY_SET;
+ case V4_0::ErrorCode::UNSUPPORTED_PURPOSE:
+ return KMV1::ErrorCode::UNSUPPORTED_PURPOSE;
+ case V4_0::ErrorCode::INCOMPATIBLE_PURPOSE:
+ return KMV1::ErrorCode::INCOMPATIBLE_PURPOSE;
+ case V4_0::ErrorCode::UNSUPPORTED_ALGORITHM:
+ return KMV1::ErrorCode::UNSUPPORTED_ALGORITHM;
+ case V4_0::ErrorCode::INCOMPATIBLE_ALGORITHM:
+ return KMV1::ErrorCode::INCOMPATIBLE_ALGORITHM;
+ case V4_0::ErrorCode::UNSUPPORTED_KEY_SIZE:
+ return KMV1::ErrorCode::UNSUPPORTED_KEY_SIZE;
+ case V4_0::ErrorCode::UNSUPPORTED_BLOCK_MODE:
+ return KMV1::ErrorCode::UNSUPPORTED_BLOCK_MODE;
+ case V4_0::ErrorCode::INCOMPATIBLE_BLOCK_MODE:
+ return KMV1::ErrorCode::INCOMPATIBLE_BLOCK_MODE;
+ case V4_0::ErrorCode::UNSUPPORTED_MAC_LENGTH:
+ return KMV1::ErrorCode::UNSUPPORTED_MAC_LENGTH;
+ case V4_0::ErrorCode::UNSUPPORTED_PADDING_MODE:
+ return KMV1::ErrorCode::UNSUPPORTED_PADDING_MODE;
+ case V4_0::ErrorCode::INCOMPATIBLE_PADDING_MODE:
+ return KMV1::ErrorCode::INCOMPATIBLE_PADDING_MODE;
+ case V4_0::ErrorCode::UNSUPPORTED_DIGEST:
+ return KMV1::ErrorCode::UNSUPPORTED_DIGEST;
+ case V4_0::ErrorCode::INCOMPATIBLE_DIGEST:
+ return KMV1::ErrorCode::INCOMPATIBLE_DIGEST;
+ case V4_0::ErrorCode::INVALID_EXPIRATION_TIME:
+ return KMV1::ErrorCode::INVALID_EXPIRATION_TIME;
+ case V4_0::ErrorCode::INVALID_USER_ID:
+ return KMV1::ErrorCode::INVALID_USER_ID;
+ case V4_0::ErrorCode::INVALID_AUTHORIZATION_TIMEOUT:
+ return KMV1::ErrorCode::INVALID_AUTHORIZATION_TIMEOUT;
+ case V4_0::ErrorCode::UNSUPPORTED_KEY_FORMAT:
+ return KMV1::ErrorCode::UNSUPPORTED_KEY_FORMAT;
+ case V4_0::ErrorCode::INCOMPATIBLE_KEY_FORMAT:
+ return KMV1::ErrorCode::INCOMPATIBLE_KEY_FORMAT;
+ case V4_0::ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:
+ return KMV1::ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM;
+ case V4_0::ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM:
+ return KMV1::ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM;
+ case V4_0::ErrorCode::INVALID_INPUT_LENGTH:
+ return KMV1::ErrorCode::INVALID_INPUT_LENGTH;
+ case V4_0::ErrorCode::KEY_EXPORT_OPTIONS_INVALID:
+ return KMV1::ErrorCode::KEY_EXPORT_OPTIONS_INVALID;
+ case V4_0::ErrorCode::DELEGATION_NOT_ALLOWED:
+ return KMV1::ErrorCode::DELEGATION_NOT_ALLOWED;
+ case V4_0::ErrorCode::KEY_NOT_YET_VALID:
+ return KMV1::ErrorCode::KEY_NOT_YET_VALID;
+ case V4_0::ErrorCode::KEY_EXPIRED:
+ return KMV1::ErrorCode::KEY_EXPIRED;
+ case V4_0::ErrorCode::KEY_USER_NOT_AUTHENTICATED:
+ return KMV1::ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+ case V4_0::ErrorCode::OUTPUT_PARAMETER_NULL:
+ return KMV1::ErrorCode::OUTPUT_PARAMETER_NULL;
+ case V4_0::ErrorCode::INVALID_OPERATION_HANDLE:
+ return KMV1::ErrorCode::INVALID_OPERATION_HANDLE;
+ case V4_0::ErrorCode::INSUFFICIENT_BUFFER_SPACE:
+ return KMV1::ErrorCode::INSUFFICIENT_BUFFER_SPACE;
+ case V4_0::ErrorCode::VERIFICATION_FAILED:
+ return KMV1::ErrorCode::VERIFICATION_FAILED;
+ case V4_0::ErrorCode::TOO_MANY_OPERATIONS:
+ return KMV1::ErrorCode::TOO_MANY_OPERATIONS;
+ case V4_0::ErrorCode::UNEXPECTED_NULL_POINTER:
+ return KMV1::ErrorCode::UNEXPECTED_NULL_POINTER;
+ case V4_0::ErrorCode::INVALID_KEY_BLOB:
+ return KMV1::ErrorCode::INVALID_KEY_BLOB;
+ case V4_0::ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED:
+ return KMV1::ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED;
+ case V4_0::ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED:
+ return KMV1::ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED;
+ case V4_0::ErrorCode::IMPORTED_KEY_NOT_SIGNED:
+ return KMV1::ErrorCode::IMPORTED_KEY_NOT_SIGNED;
+ case V4_0::ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED:
+ return KMV1::ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED;
+ case V4_0::ErrorCode::INVALID_ARGUMENT:
+ return KMV1::ErrorCode::INVALID_ARGUMENT;
+ case V4_0::ErrorCode::UNSUPPORTED_TAG:
+ return KMV1::ErrorCode::UNSUPPORTED_TAG;
+ case V4_0::ErrorCode::INVALID_TAG:
+ return KMV1::ErrorCode::INVALID_TAG;
+ case V4_0::ErrorCode::MEMORY_ALLOCATION_FAILED:
+ return KMV1::ErrorCode::MEMORY_ALLOCATION_FAILED;
+ case V4_0::ErrorCode::IMPORT_PARAMETER_MISMATCH:
+ return KMV1::ErrorCode::IMPORT_PARAMETER_MISMATCH;
+ case V4_0::ErrorCode::SECURE_HW_ACCESS_DENIED:
+ return KMV1::ErrorCode::SECURE_HW_ACCESS_DENIED;
+ case V4_0::ErrorCode::OPERATION_CANCELLED:
+ return KMV1::ErrorCode::OPERATION_CANCELLED;
+ case V4_0::ErrorCode::CONCURRENT_ACCESS_CONFLICT:
+ return KMV1::ErrorCode::CONCURRENT_ACCESS_CONFLICT;
+ case V4_0::ErrorCode::SECURE_HW_BUSY:
+ return KMV1::ErrorCode::SECURE_HW_BUSY;
+ case V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED:
+ return KMV1::ErrorCode::SECURE_HW_COMMUNICATION_FAILED;
+ case V4_0::ErrorCode::UNSUPPORTED_EC_FIELD:
+ return KMV1::ErrorCode::UNSUPPORTED_EC_FIELD;
+ case V4_0::ErrorCode::MISSING_NONCE:
+ return KMV1::ErrorCode::MISSING_NONCE;
+ case V4_0::ErrorCode::INVALID_NONCE:
+ return KMV1::ErrorCode::INVALID_NONCE;
+ case V4_0::ErrorCode::MISSING_MAC_LENGTH:
+ return KMV1::ErrorCode::MISSING_MAC_LENGTH;
+ case V4_0::ErrorCode::KEY_RATE_LIMIT_EXCEEDED:
+ return KMV1::ErrorCode::KEY_RATE_LIMIT_EXCEEDED;
+ case V4_0::ErrorCode::CALLER_NONCE_PROHIBITED:
+ return KMV1::ErrorCode::CALLER_NONCE_PROHIBITED;
+ case V4_0::ErrorCode::KEY_MAX_OPS_EXCEEDED:
+ return KMV1::ErrorCode::KEY_MAX_OPS_EXCEEDED;
+ case V4_0::ErrorCode::INVALID_MAC_LENGTH:
+ return KMV1::ErrorCode::INVALID_MAC_LENGTH;
+ case V4_0::ErrorCode::MISSING_MIN_MAC_LENGTH:
+ return KMV1::ErrorCode::MISSING_MIN_MAC_LENGTH;
+ case V4_0::ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH:
+ return KMV1::ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH;
+ case V4_0::ErrorCode::UNSUPPORTED_KDF:
+ return KMV1::ErrorCode::UNSUPPORTED_KDF;
+ case V4_0::ErrorCode::UNSUPPORTED_EC_CURVE:
+ return KMV1::ErrorCode::UNSUPPORTED_EC_CURVE;
+ case V4_0::ErrorCode::KEY_REQUIRES_UPGRADE:
+ return KMV1::ErrorCode::KEY_REQUIRES_UPGRADE;
+ case V4_0::ErrorCode::ATTESTATION_CHALLENGE_MISSING:
+ return KMV1::ErrorCode::ATTESTATION_CHALLENGE_MISSING;
+ case V4_0::ErrorCode::KEYMASTER_NOT_CONFIGURED:
+ return KMV1::ErrorCode::KEYMINT_NOT_CONFIGURED;
+ case V4_0::ErrorCode::ATTESTATION_APPLICATION_ID_MISSING:
+ return KMV1::ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
+ case V4_0::ErrorCode::CANNOT_ATTEST_IDS:
+ return KMV1::ErrorCode::CANNOT_ATTEST_IDS;
+ case V4_0::ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE:
+ return KMV1::ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE;
+ case V4_0::ErrorCode::HARDWARE_TYPE_UNAVAILABLE:
+ return KMV1::ErrorCode::HARDWARE_TYPE_UNAVAILABLE;
+ case V4_0::ErrorCode::PROOF_OF_PRESENCE_REQUIRED:
+ return KMV1::ErrorCode::PROOF_OF_PRESENCE_REQUIRED;
+ case V4_0::ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED:
+ return KMV1::ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED;
+ case V4_0::ErrorCode::NO_USER_CONFIRMATION:
+ return KMV1::ErrorCode::NO_USER_CONFIRMATION;
+ case V4_0::ErrorCode::DEVICE_LOCKED:
+ return KMV1::ErrorCode::DEVICE_LOCKED;
+ case V4_0::ErrorCode::UNIMPLEMENTED:
+ return KMV1::ErrorCode::UNIMPLEMENTED;
+ case V4_0::ErrorCode::VERSION_MISMATCH:
+ return KMV1::ErrorCode::VERSION_MISMATCH;
+ case V4_0::ErrorCode::UNKNOWN_ERROR:
+ return KMV1::ErrorCode::UNKNOWN_ERROR;
+ }
+}
+
static std::optional<V4_0::KeyPurpose> convert(KMV1::KeyPurpose p) {
switch (p) {
case KMV1::KeyPurpose::ENCRYPT:
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index 7814364..d264e7a 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -39,23 +39,32 @@
static COMPAT_NAME: &str = "android.security.compat";
- fn get_device() -> Box<dyn IKeyMintDevice> {
+ fn get_device() -> Option<Box<dyn IKeyMintDevice>> {
add_keymint_device_service();
let compat_service: Box<dyn IKeystoreCompatService> =
- binder::get_interface(COMPAT_NAME).unwrap();
- compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap()
+ binder::get_interface(COMPAT_NAME).ok()?;
+ compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
+ }
+
+ macro_rules! get_device_or_skip_test {
+ () => {
+ match get_device() {
+ Some(dev) => dev,
+ None => return,
+ }
+ };
}
#[test]
fn test_get_hardware_info() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let hinfo = legacy.getHardwareInfo();
assert!(hinfo.is_ok());
}
#[test]
fn test_add_rng_entropy() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let result = legacy.addRngEntropy(&[42; 16]);
assert!(result.is_ok(), "{:?}", result);
}
@@ -117,25 +126,25 @@
#[test]
fn test_generate_key_no_encrypt() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
generate_rsa_key(legacy.as_ref(), false, false);
}
#[test]
fn test_generate_key_encrypt() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
generate_rsa_key(legacy.as_ref(), true, false);
}
#[test]
fn test_generate_key_attested() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
generate_rsa_key(legacy.as_ref(), false, true);
}
#[test]
fn test_import_key() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let kps = [KeyParameter {
tag: Tag::ALGORITHM,
value: KeyParameterValue::Algorithm(Algorithm::AES),
@@ -149,7 +158,7 @@
#[test]
fn test_import_wrapped_key() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
// For this test we only care that there was no crash.
assert!(result.is_ok() || result.is_err());
@@ -157,7 +166,7 @@
#[test]
fn test_upgrade_key() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let blob = generate_rsa_key(legacy.as_ref(), false, false);
let result = legacy.upgradeKey(&blob, &[]);
// For this test we only care that there was no crash.
@@ -166,7 +175,7 @@
#[test]
fn test_delete_key() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let blob = generate_rsa_key(legacy.as_ref(), false, false);
let result = legacy.deleteKey(&blob);
assert!(result.is_ok(), "{:?}", result);
@@ -174,14 +183,14 @@
#[test]
fn test_delete_all_keys() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let result = legacy.deleteAllKeys();
assert!(result.is_ok(), "{:?}", result);
}
#[test]
fn test_destroy_attestation_ids() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let result = legacy.destroyAttestationIds();
assert!(result.is_err());
assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
@@ -243,7 +252,7 @@
#[test]
fn test_begin_abort() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let blob = generate_aes_key(legacy.as_ref());
let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
let operation = begin_result.operation.unwrap();
@@ -255,7 +264,7 @@
#[test]
fn test_begin_update_finish() {
- let legacy = get_device();
+ let legacy = get_device_or_skip_test!();
let blob = generate_aes_key(legacy.as_ref());
let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
diff --git a/keystore2/src/km_compat/parameter_conversion_test.cpp b/keystore2/src/km_compat/parameter_conversion_test.cpp
index 41be067..48af20c 100644
--- a/keystore2/src/km_compat/parameter_conversion_test.cpp
+++ b/keystore2/src/km_compat/parameter_conversion_test.cpp
@@ -150,3 +150,84 @@
TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_SECURE_ID);
TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_VENDOR_PATCHLEVEL);
}
+
+#define TEST_ERROR_CODE_CONVERSION(variant) \
+ ASSERT_EQ(KMV1::ErrorCode::variant, convert(V4_0::ErrorCode::variant))
+
+TEST(KmCompatTypeConversionTest, testErrorCodeConversion) {
+ TEST_ERROR_CODE_CONVERSION(OK);
+ TEST_ERROR_CODE_CONVERSION(ROOT_OF_TRUST_ALREADY_SET);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_PURPOSE);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_PURPOSE);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_ALGORITHM);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_ALGORITHM);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_SIZE);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_BLOCK_MODE);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_BLOCK_MODE);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_MAC_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_PADDING_MODE);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_PADDING_MODE);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_DIGEST);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_DIGEST);
+ TEST_ERROR_CODE_CONVERSION(INVALID_EXPIRATION_TIME);
+ TEST_ERROR_CODE_CONVERSION(INVALID_USER_ID);
+ TEST_ERROR_CODE_CONVERSION(INVALID_AUTHORIZATION_TIMEOUT);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_FORMAT);
+ TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_KEY_FORMAT);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_VERIFICATION_ALGORITHM);
+ TEST_ERROR_CODE_CONVERSION(INVALID_INPUT_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(KEY_EXPORT_OPTIONS_INVALID);
+ TEST_ERROR_CODE_CONVERSION(DELEGATION_NOT_ALLOWED);
+ TEST_ERROR_CODE_CONVERSION(KEY_NOT_YET_VALID);
+ TEST_ERROR_CODE_CONVERSION(KEY_EXPIRED);
+ TEST_ERROR_CODE_CONVERSION(KEY_USER_NOT_AUTHENTICATED);
+ TEST_ERROR_CODE_CONVERSION(OUTPUT_PARAMETER_NULL);
+ TEST_ERROR_CODE_CONVERSION(INVALID_OPERATION_HANDLE);
+ TEST_ERROR_CODE_CONVERSION(INSUFFICIENT_BUFFER_SPACE);
+ TEST_ERROR_CODE_CONVERSION(VERIFICATION_FAILED);
+ TEST_ERROR_CODE_CONVERSION(TOO_MANY_OPERATIONS);
+ TEST_ERROR_CODE_CONVERSION(UNEXPECTED_NULL_POINTER);
+ TEST_ERROR_CODE_CONVERSION(INVALID_KEY_BLOB);
+ TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_NOT_ENCRYPTED);
+ TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_DECRYPTION_FAILED);
+ TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_NOT_SIGNED);
+ TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_VERIFICATION_FAILED);
+ TEST_ERROR_CODE_CONVERSION(INVALID_ARGUMENT);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_TAG);
+ TEST_ERROR_CODE_CONVERSION(INVALID_TAG);
+ TEST_ERROR_CODE_CONVERSION(MEMORY_ALLOCATION_FAILED);
+ TEST_ERROR_CODE_CONVERSION(IMPORT_PARAMETER_MISMATCH);
+ TEST_ERROR_CODE_CONVERSION(SECURE_HW_ACCESS_DENIED);
+ TEST_ERROR_CODE_CONVERSION(OPERATION_CANCELLED);
+ TEST_ERROR_CODE_CONVERSION(CONCURRENT_ACCESS_CONFLICT);
+ TEST_ERROR_CODE_CONVERSION(SECURE_HW_BUSY);
+ TEST_ERROR_CODE_CONVERSION(SECURE_HW_COMMUNICATION_FAILED);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_EC_FIELD);
+ TEST_ERROR_CODE_CONVERSION(MISSING_NONCE);
+ TEST_ERROR_CODE_CONVERSION(INVALID_NONCE);
+ TEST_ERROR_CODE_CONVERSION(MISSING_MAC_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(KEY_RATE_LIMIT_EXCEEDED);
+ TEST_ERROR_CODE_CONVERSION(CALLER_NONCE_PROHIBITED);
+ TEST_ERROR_CODE_CONVERSION(KEY_MAX_OPS_EXCEEDED);
+ TEST_ERROR_CODE_CONVERSION(INVALID_MAC_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(MISSING_MIN_MAC_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_MIN_MAC_LENGTH);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KDF);
+ TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_EC_CURVE);
+ TEST_ERROR_CODE_CONVERSION(KEY_REQUIRES_UPGRADE);
+ TEST_ERROR_CODE_CONVERSION(ATTESTATION_CHALLENGE_MISSING);
+ ASSERT_EQ(KMV1::ErrorCode::KEYMINT_NOT_CONFIGURED,
+ convert(V4_0::ErrorCode::KEYMASTER_NOT_CONFIGURED));
+ TEST_ERROR_CODE_CONVERSION(ATTESTATION_APPLICATION_ID_MISSING);
+ TEST_ERROR_CODE_CONVERSION(CANNOT_ATTEST_IDS);
+ TEST_ERROR_CODE_CONVERSION(ROLLBACK_RESISTANCE_UNAVAILABLE);
+ TEST_ERROR_CODE_CONVERSION(HARDWARE_TYPE_UNAVAILABLE);
+ TEST_ERROR_CODE_CONVERSION(PROOF_OF_PRESENCE_REQUIRED);
+ TEST_ERROR_CODE_CONVERSION(CONCURRENT_PROOF_OF_PRESENCE_REQUESTED);
+ TEST_ERROR_CODE_CONVERSION(NO_USER_CONFIRMATION);
+ TEST_ERROR_CODE_CONVERSION(DEVICE_LOCKED);
+ TEST_ERROR_CODE_CONVERSION(UNIMPLEMENTED);
+ TEST_ERROR_CODE_CONVERSION(VERSION_MISMATCH);
+ TEST_ERROR_CODE_CONVERSION(UNKNOWN_ERROR);
+}
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index 829987d..97bab77 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -368,7 +368,6 @@
self.touch();
let mut out_params: Option<KeyParameterArray> = None;
- let mut output: Option<ByteArray> = None;
let km_op: Box<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
@@ -380,28 +379,39 @@
.before_update()
.context("In update: Trying to get auth tokens.")?;
- self.update_outcome(
- &mut *outcome,
- map_km_error(km_op.update(
- None,
- Some(input),
- hat.as_ref(),
- tst.as_ref(),
- &mut out_params,
- &mut output,
- )),
- )
- .context("In update: KeyMint::update failed.")?;
+ let mut result: Option<Vec<u8>> = None;
+ let mut consumed = 0usize;
+ loop {
+ let mut output: Option<ByteArray> = None;
+ consumed += self
+ .update_outcome(
+ &mut *outcome,
+ map_km_error(km_op.update(
+ None,
+ Some(&input[consumed..]),
+ hat.as_ref(),
+ tst.as_ref(),
+ &mut out_params,
+ &mut output,
+ )),
+ )
+ .context("In update: KeyMint::update failed.")? as usize;
- match output {
- Some(blob) => {
- if blob.data.is_empty() {
- Ok(None)
- } else {
- Ok(Some(blob.data))
+ match (output, &mut result) {
+ (Some(blob), None) => {
+ if !blob.data.is_empty() {
+ result = Some(blob.data)
+ }
}
+ (Some(mut blob), Some(ref mut result)) => {
+ result.append(&mut blob.data);
+ }
+ (None, _) => {}
}
- None => Ok(None),
+
+ if consumed == input.len() {
+ return Ok(result);
+ }
}
}
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index a81954f..0f0ca04 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -454,9 +454,12 @@
for p in access_vec.into_iter() {
selinux::check_access(caller_ctx, &target_context, "keystore2_key", p.to_selinux())
- .context(concat!(
- "check_grant_permission: check_access failed. ",
- "The caller may have tried to grant a permission that they don't possess."
+ .context(format!(
+ concat!(
+ "check_grant_permission: check_access failed. ",
+ "The caller may have tried to grant a permission that they don't possess. {:?}"
+ ),
+ p
))?
}
Ok(())
@@ -575,6 +578,16 @@
KeyPerm::use_(),
];
+ const SYSTEM_SERVER_PERMISSIONS_NO_GRANT: KeyPermSet = key_perm_set![
+ KeyPerm::delete(),
+ KeyPerm::use_dev_id(),
+ // No KeyPerm::grant()
+ KeyPerm::get_info(),
+ KeyPerm::rebind(),
+ KeyPerm::update(),
+ KeyPerm::use_(),
+ ];
+
const NOT_GRANT_PERMS: KeyPermSet = key_perm_set![
KeyPerm::manage_blob(),
KeyPerm::delete(),
@@ -643,7 +656,6 @@
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::add_auth()).is_ok());
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::clear_ns()).is_ok());
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::get_state()).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::list()).is_ok());
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::lock()).is_ok());
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::reset()).is_ok());
assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::unlock()).is_ok());
@@ -663,9 +675,10 @@
let system_server_ctx = Context::new("u:r:system_server:s0")?;
let shell_ctx = Context::new("u:r:shell:s0")?;
let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
- assert!(check_grant_permission(&system_server_ctx, NOT_GRANT_PERMS, &key).is_ok());
- // attempts to grant the grant permission must always fail even when privileged.
+ check_grant_permission(&system_server_ctx, SYSTEM_SERVER_PERMISSIONS_NO_GRANT, &key)
+ .expect("Grant permission check failed.");
+ // attempts to grant the grant permission must always fail even when privileged.
assert_perm_failed!(check_grant_permission(
&system_server_ctx,
KeyPerm::grant().into(),