Keystore 2.0: Revise Legacy wrapper error handling

Now using mostly KeyMint error codes and a safe conversion function.

Test: keystore2_km_compat_test_cpp

Change-Id: I43ec848a8ee5544fcc8e79a4af0690e45bc28095
This commit is contained in:
Janis Danisevskis 2021-01-30 22:33:11 -08:00
parent f3caf2698b
commit 926a6c032f
4 changed files with 342 additions and 102 deletions

View file

@ -52,19 +52,23 @@ namespace KMV1 = ::aidl::android::hardware::security::keymint;
// Utility functions // Utility functions
// Converts a V4 error code into a ScopedAStatus ScopedAStatus convertErrorCode(KMV1::ErrorCode result) {
ScopedAStatus convertErrorCode(V4_0_ErrorCode result) { if (result == KMV1::ErrorCode::OK) {
if (result == V4_0_ErrorCode::OK) {
return ScopedAStatus::ok(); return ScopedAStatus::ok();
} }
return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result)); 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) { if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
return static_cast<V4_0_ErrorCode>(status.getServiceSpecificError()); return static_cast<KMV1::ErrorCode>(status.getServiceSpecificError());
} else { } else {
return V4_0_ErrorCode::UNKNOWN_ERROR; return KMV1::ErrorCode::UNKNOWN_ERROR;
} }
} }
@ -174,25 +178,27 @@ ScopedAStatus KeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* _aidl_return)
_aidl_return->keyMintAuthorName = keymasterAuthorName; _aidl_return->keyMintAuthorName = keymasterAuthorName;
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return ScopedAStatus::ok(); return ScopedAStatus::ok();
} }
ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector<uint8_t>& in_data) { ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector<uint8_t>& in_data) {
V4_0_ErrorCode errorCode = mDevice->addRngEntropy(in_data); auto result = mDevice->addRngEntropy(in_data);
return convertErrorCode(errorCode); if (!result.isOk()) {
return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(result);
} }
ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& in_keyParams, ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& in_keyParams,
KeyCreationResult* out_creationResult) { KeyCreationResult* out_creationResult) {
auto legacyKeyParams = convertKeyParametersToLegacy(in_keyParams); auto legacyKeyParams = convertKeyParametersToLegacy(in_keyParams);
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->generateKey( auto result = mDevice->generateKey(
legacyKeyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob, legacyKeyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) { const V4_0_KeyCharacteristics& keyCharacteristics) {
errorCode = error; errorCode = convert(error);
out_creationResult->keyBlob = keyBlob; out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics = out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics); convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics);
@ -201,12 +207,12 @@ ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& in_key
return ScopedAStatus::fromServiceSpecificError( return ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR)); 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); auto cert = getCertificate(in_keyParams, out_creationResult->keyBlob);
if (std::holds_alternative<V4_0_ErrorCode>(cert)) { if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
auto code = std::get<V4_0_ErrorCode>(cert); auto code = std::get<KMV1::ErrorCode>(cert);
// We return OK in successful cases that do not generate a certificate. // 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; errorCode = code;
deleteKey(out_creationResult->keyBlob); deleteKey(out_creationResult->keyBlob);
} }
@ -223,26 +229,25 @@ ScopedAStatus KeyMintDevice::importKey(const std::vector<KeyParameter>& in_inKey
KeyCreationResult* out_creationResult) { KeyCreationResult* out_creationResult) {
auto legacyKeyParams = convertKeyParametersToLegacy(in_inKeyParams); auto legacyKeyParams = convertKeyParametersToLegacy(in_inKeyParams);
auto legacyKeyFormat = convertKeyFormatToLegacy(in_inKeyFormat); auto legacyKeyFormat = convertKeyFormatToLegacy(in_inKeyFormat);
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->importKey(legacyKeyParams, legacyKeyFormat, in_inKeyData, auto result = mDevice->importKey(legacyKeyParams, legacyKeyFormat, in_inKeyData,
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) { const V4_0_KeyCharacteristics& keyCharacteristics) {
errorCode = error; errorCode = convert(error);
out_creationResult->keyBlob = keyBlob; out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics = out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy( convertKeyCharacteristicsFromLegacy(
securityLevel_, keyCharacteristics); securityLevel_, keyCharacteristics);
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
if (errorCode == V4_0_ErrorCode::OK) { if (errorCode == KMV1::ErrorCode::OK) {
auto cert = getCertificate(in_inKeyParams, out_creationResult->keyBlob); auto cert = getCertificate(in_inKeyParams, out_creationResult->keyBlob);
if (std::holds_alternative<V4_0_ErrorCode>(cert)) { if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
auto code = std::get<V4_0_ErrorCode>(cert); auto code = std::get<KMV1::ErrorCode>(cert);
// We return OK in successful cases that do not generate a certificate. // 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; errorCode = code;
deleteKey(out_creationResult->keyBlob); deleteKey(out_creationResult->keyBlob);
} }
@ -259,20 +264,19 @@ ScopedAStatus KeyMintDevice::importWrappedKey(
const std::vector<KeyParameter>& in_inUnwrappingParams, int64_t in_inPasswordSid, const std::vector<KeyParameter>& in_inUnwrappingParams, int64_t in_inPasswordSid,
int64_t in_inBiometricSid, KeyCreationResult* out_creationResult) { int64_t in_inBiometricSid, KeyCreationResult* out_creationResult) {
auto legacyUnwrappingParams = convertKeyParametersToLegacy(in_inUnwrappingParams); auto legacyUnwrappingParams = convertKeyParametersToLegacy(in_inUnwrappingParams);
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->importWrappedKey( auto result = mDevice->importWrappedKey(
in_inWrappedKeyData, in_inWrappingKeyBlob, in_inMaskingKey, legacyUnwrappingParams, in_inWrappedKeyData, in_inWrappingKeyBlob, in_inMaskingKey, legacyUnwrappingParams,
in_inPasswordSid, in_inBiometricSid, in_inPasswordSid, in_inBiometricSid,
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
const V4_0_KeyCharacteristics& keyCharacteristics) { const V4_0_KeyCharacteristics& keyCharacteristics) {
errorCode = error; errorCode = convert(error);
out_creationResult->keyBlob = keyBlob; out_creationResult->keyBlob = keyBlob;
out_creationResult->keyCharacteristics = out_creationResult->keyCharacteristics =
convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics); convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics);
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
@ -289,20 +293,25 @@ ScopedAStatus KeyMintDevice::upgradeKey(const std::vector<uint8_t>& in_inKeyBlob
*_aidl_return = upgradedKeyBlob; *_aidl_return = upgradedKeyBlob;
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
ScopedAStatus KeyMintDevice::deleteKey(const std::vector<uint8_t>& in_inKeyBlob) { ScopedAStatus KeyMintDevice::deleteKey(const std::vector<uint8_t>& in_inKeyBlob) {
V4_0_ErrorCode errorCode = mDevice->deleteKey(in_inKeyBlob); auto result = mDevice->deleteKey(in_inKeyBlob);
return convertErrorCode(errorCode); if (!result.isOk()) {
return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(result);
} }
ScopedAStatus KeyMintDevice::deleteAllKeys() { ScopedAStatus KeyMintDevice::deleteAllKeys() {
V4_0_ErrorCode errorCode = mDevice->deleteAllKeys(); auto result = mDevice->deleteAllKeys();
return convertErrorCode(errorCode); if (!result.isOk()) {
return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(result);
} }
// We're not implementing this. // We're not implementing this.
@ -323,24 +332,21 @@ ScopedAStatus KeyMintDevice::begin(KeyPurpose in_inPurpose,
static_cast<::android::hardware::keymaster::V4_0::KeyPurpose>(in_inPurpose); static_cast<::android::hardware::keymaster::V4_0::KeyPurpose>(in_inPurpose);
auto legacyParams = convertKeyParametersToLegacy(in_inParams); auto legacyParams = convertKeyParametersToLegacy(in_inParams);
auto legacyAuthToken = convertAuthTokenToLegacy(in_inAuthToken); auto legacyAuthToken = convertAuthTokenToLegacy(in_inAuthToken);
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->begin( auto result = mDevice->begin(
legacyPurpose, in_inKeyBlob, legacyParams, legacyAuthToken, legacyPurpose, in_inKeyBlob, legacyParams, legacyAuthToken,
[&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams, [&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
uint64_t operationHandle) { uint64_t operationHandle) {
errorCode = error; errorCode = convert(error);
_aidl_return->challenge = operationHandle; // TODO: Is this right? _aidl_return->challenge = operationHandle;
_aidl_return->params = convertKeyParametersFromLegacy(outParams); _aidl_return->params = convertKeyParametersFromLegacy(outParams);
_aidl_return->operation = ndk::SharedRefBase::make<KeyMintOperation>( _aidl_return->operation = ndk::SharedRefBase::make<KeyMintOperation>(
mDevice, operationHandle, &mOperationSlots, error == V4_0_ErrorCode::OK); mDevice, operationHandle, &mOperationSlots, error == V4_0_ErrorCode::OK);
}); });
if (!result.isOk()) { if (!result.isOk()) {
// TODO: In this case we're guaranteed that _aidl_return was not initialized, right? errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
mOperationSlots.freeSlot();
return ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
if (errorCode != V4_0_ErrorCode::OK) { if (errorCode != KMV1::ErrorCode::OK) {
mOperationSlots.freeSlot(); mOperationSlots.freeSlot();
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
@ -366,12 +372,12 @@ ScopedAStatus KeyMintOperation::update(const std::optional<KeyParameterArray>& i
if (in_inTimeStampToken.has_value()) { if (in_inTimeStampToken.has_value()) {
verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value()); verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
} }
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->update( auto result = mDevice->update(
mOperationHandle, legacyParams, input, authToken, verificationToken, mOperationHandle, legacyParams, input, authToken, verificationToken,
[&](V4_0_ErrorCode error, uint32_t inputConsumed, [&](V4_0_ErrorCode error, uint32_t inputConsumed,
const hidl_vec<V4_0_KeyParameter>& outParams, const hidl_vec<uint8_t>& output) { const hidl_vec<V4_0_KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
errorCode = error; errorCode = convert(error);
out_outParams->emplace(); out_outParams->emplace();
out_outParams->value().params = convertKeyParametersFromLegacy(outParams); out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
out_output->emplace(); out_output->emplace();
@ -379,11 +385,9 @@ ScopedAStatus KeyMintOperation::update(const std::optional<KeyParameterArray>& i
*_aidl_return = inputConsumed; *_aidl_return = inputConsumed;
}); });
if (!result.isOk()) { if (!result.isOk()) {
mOperationSlot.freeSlot(); errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
return ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
if (errorCode != V4_0_ErrorCode::OK) { if (errorCode != KMV1::ErrorCode::OK) {
mOperationSlot.freeSlot(); mOperationSlot.freeSlot();
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
@ -396,7 +400,7 @@ ScopedAStatus KeyMintOperation::finish(const std::optional<KeyParameterArray>& i
const std::optional<TimeStampToken>& in_inTimeStampToken, const std::optional<TimeStampToken>& in_inTimeStampToken,
std::optional<KeyParameterArray>* out_outParams, std::optional<KeyParameterArray>* out_outParams,
std::vector<uint8_t>* _aidl_return) { std::vector<uint8_t>* _aidl_return) {
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
std::vector<V4_0_KeyParameter> legacyParams; std::vector<V4_0_KeyParameter> legacyParams;
if (in_inParams.has_value()) { if (in_inParams.has_value()) {
legacyParams = convertKeyParametersToLegacy(in_inParams.value().params); legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
@ -415,23 +419,25 @@ ScopedAStatus KeyMintOperation::finish(const std::optional<KeyParameterArray>& i
mOperationHandle, legacyParams, input, signature, authToken, verificationToken, mOperationHandle, legacyParams, input, signature, authToken, verificationToken,
[&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams, [&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
const hidl_vec<uint8_t>& output) { const hidl_vec<uint8_t>& output) {
errorCode = error; errorCode = convert(error);
out_outParams->emplace(); out_outParams->emplace();
out_outParams->value().params = convertKeyParametersFromLegacy(outParams); out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
*_aidl_return = output; *_aidl_return = output;
}); });
mOperationSlot.freeSlot(); mOperationSlot.freeSlot();
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
ScopedAStatus KeyMintOperation::abort() { ScopedAStatus KeyMintOperation::abort() {
V4_0_ErrorCode errorCode = mDevice->abort(mOperationHandle); auto result = mDevice->abort(mOperationHandle);
mOperationSlot.freeSlot(); mOperationSlot.freeSlot();
return convertErrorCode(errorCode); if (!result.isOk()) {
return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
}
return convertErrorCode(result);
} }
KeyMintOperation::~KeyMintOperation() { KeyMintOperation::~KeyMintOperation() {
@ -446,18 +452,17 @@ KeyMintOperation::~KeyMintOperation() {
// SecureClock implementation // SecureClock implementation
ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToken* _aidl_return) { ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToken* _aidl_return) {
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->verifyAuthorization( auto result = mDevice->verifyAuthorization(
in_challenge, {}, V4_0_HardwareAuthToken(), in_challenge, {}, V4_0_HardwareAuthToken(),
[&](V4_0_ErrorCode error, const V4_0_VerificationToken& token) { [&](V4_0_ErrorCode error, const V4_0_VerificationToken& token) {
errorCode = error; errorCode = convert(error);
_aidl_return->challenge = token.challenge; _aidl_return->challenge = token.challenge;
_aidl_return->timestamp.milliSeconds = token.timestamp; _aidl_return->timestamp.milliSeconds = token.timestamp;
_aidl_return->mac = token.mac; _aidl_return->mac = token.mac;
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
@ -465,17 +470,16 @@ ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToke
// SharedSecret implementation // SharedSecret implementation
ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _aidl_return) { ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _aidl_return) {
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto result = mDevice->getHmacSharingParameters( auto result = mDevice->getHmacSharingParameters(
[&](V4_0_ErrorCode error, const V4_0_HmacSharingParameters& params) { [&](V4_0_ErrorCode error, const V4_0_HmacSharingParameters& params) {
errorCode = error; errorCode = convert(error);
_aidl_return->seed = params.seed; _aidl_return->seed = params.seed;
std::copy(params.nonce.data(), params.nonce.data() + params.nonce.elementCount(), std::copy(params.nonce.data(), params.nonce.data() + params.nonce.elementCount(),
std::back_inserter(_aidl_return->nonce)); std::back_inserter(_aidl_return->nonce));
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
@ -483,16 +487,15 @@ ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _a
ScopedAStatus ScopedAStatus
SharedSecret::computeSharedSecret(const std::vector<SharedSecretParameters>& in_params, SharedSecret::computeSharedSecret(const std::vector<SharedSecretParameters>& in_params,
std::vector<uint8_t>* _aidl_return) { std::vector<uint8_t>* _aidl_return) {
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
auto legacyParams = convertSharedSecretParametersToLegacy(in_params); auto legacyParams = convertSharedSecretParametersToLegacy(in_params);
auto result = mDevice->computeSharedHmac( auto result = mDevice->computeSharedHmac(
legacyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& sharingCheck) { legacyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& sharingCheck) {
errorCode = error; errorCode = convert(error);
*_aidl_return = sharingCheck; *_aidl_return = sharingCheck;
}); });
if (!result.isOk()) { if (!result.isOk()) {
return ScopedAStatus::fromServiceSpecificError( errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
} }
return convertErrorCode(errorCode); return convertErrorCode(errorCode);
} }
@ -536,12 +539,12 @@ getMaximum(const std::vector<KeyParameter>& keyParams, T tag,
return *bestSoFar; 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, makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob) { const std::vector<uint8_t>& keyBlob) {
// Start generating the certificate. // Start generating the certificate.
// Get public key for makeCert. // Get public key for makeCert.
V4_0_ErrorCode errorCode; KMV1::ErrorCode errorCode;
std::vector<uint8_t> key; std::vector<uint8_t> key;
static std::vector<uint8_t> empty_vector; static std::vector<uint8_t> empty_vector;
auto unwrapBlob = [&](auto b) -> const std::vector<uint8_t>& { auto unwrapBlob = [&](auto b) -> const std::vector<uint8_t>& {
@ -554,13 +557,13 @@ makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyP
V4_0_KeyFormat::X509, keyBlob, unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_ID)), V4_0_KeyFormat::X509, keyBlob, unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_ID)),
unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_DATA)), unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_DATA)),
[&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) { [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
errorCode = error; errorCode = convert(error);
key = keyMaterial; key = keyMaterial;
}); });
if (!result.isOk()) { 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; return errorCode;
} }
// Get pkey for makeCert. // Get pkey for makeCert.
@ -585,12 +588,12 @@ makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyP
std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */); std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */);
if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) { if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) {
LOG(ERROR) << __func__ << ": Failed to make certificate"; 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)); 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) { switch (algorithm) {
case Algorithm::RSA: case Algorithm::RSA:
return keystore::Algo::RSA; return keystore::Algo::RSA;
@ -598,11 +601,11 @@ static std::variant<keystore::Algo, V4_0_ErrorCode> getKeystoreAlgorithm(Algorit
return keystore::Algo::ECDSA; return keystore::Algo::ECDSA;
default: default:
LOG(ERROR) << __func__ << ": This should not be called with symmetric algorithm."; 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) { switch (padding) {
case PaddingMode::RSA_PKCS1_1_5_SIGN: case PaddingMode::RSA_PKCS1_1_5_SIGN:
return keystore::Padding::PKCS1_5; return keystore::Padding::PKCS1_5;
@ -613,7 +616,7 @@ static std::variant<keystore::Padding, V4_0_ErrorCode> getKeystorePadding(Paddin
} }
} }
static std::variant<keystore::Digest, V4_0_ErrorCode> getKeystoreDigest(Digest digest) { static std::variant<keystore::Digest, KMV1::ErrorCode> getKeystoreDigest(Digest digest) {
switch (digest) { switch (digest) {
case Digest::SHA1: case Digest::SHA1:
return keystore::Digest::SHA1; return keystore::Digest::SHA1;
@ -628,36 +631,36 @@ static std::variant<keystore::Digest, V4_0_ErrorCode> getKeystoreDigest(Digest d
return keystore::Digest::SHA512; return keystore::Digest::SHA512;
default: default:
LOG(ERROR) << __func__ << ": Unknown digest."; 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, KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob, X509* cert) { const std::vector<uint8_t>& keyBlob, X509* cert) {
auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM); auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
auto algoOrError = getKeystoreAlgorithm(*algorithm); auto algoOrError = getKeystoreAlgorithm(*algorithm);
if (std::holds_alternative<V4_0_ErrorCode>(algoOrError)) { if (std::holds_alternative<KMV1::ErrorCode>(algoOrError)) {
return std::get<V4_0_ErrorCode>(algoOrError); return std::get<KMV1::ErrorCode>(algoOrError);
} }
auto algo = std::get<keystore::Algo>(algoOrError); auto algo = std::get<keystore::Algo>(algoOrError);
auto origPadding = getMaximum(keyParams, KMV1::TAG_PADDING, auto origPadding = getMaximum(keyParams, KMV1::TAG_PADDING,
{PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}); {PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN});
auto paddingOrError = getKeystorePadding(origPadding); auto paddingOrError = getKeystorePadding(origPadding);
if (std::holds_alternative<V4_0_ErrorCode>(paddingOrError)) { if (std::holds_alternative<KMV1::ErrorCode>(paddingOrError)) {
return std::get<V4_0_ErrorCode>(paddingOrError); return std::get<KMV1::ErrorCode>(paddingOrError);
} }
auto padding = std::get<keystore::Padding>(paddingOrError); auto padding = std::get<keystore::Padding>(paddingOrError);
auto origDigest = getMaximum( auto origDigest = getMaximum(
keyParams, KMV1::TAG_DIGEST, keyParams, KMV1::TAG_DIGEST,
{Digest::SHA_2_256, Digest::SHA_2_512, Digest::SHA_2_384, Digest::SHA_2_224, Digest::SHA1}); {Digest::SHA_2_256, Digest::SHA_2_512, Digest::SHA_2_384, Digest::SHA_2_224, Digest::SHA1});
auto digestOrError = getKeystoreDigest(origDigest); auto digestOrError = getKeystoreDigest(origDigest);
if (std::holds_alternative<V4_0_ErrorCode>(digestOrError)) { if (std::holds_alternative<KMV1::ErrorCode>(digestOrError)) {
return std::get<V4_0_ErrorCode>(digestOrError); return std::get<KMV1::ErrorCode>(digestOrError);
} }
auto digest = std::get<keystore::Digest>(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( auto error = keystore::signCertWith(
&*cert, &*cert,
[&](const uint8_t* data, size_t len) { [&](const uint8_t* data, size_t len) {
@ -694,40 +697,40 @@ KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
if (error) { if (error) {
LOG(ERROR) << __func__ LOG(ERROR) << __func__
<< ": signCertWith failed. (Callback diagnosed: " << toString(errorCode) << ")"; << ": 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 errorCode;
} }
return std::nullopt; 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, KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
const std::vector<uint8_t>& keyBlob) { const std::vector<uint8_t>& keyBlob) {
// There are no certificates for symmetric keys. // There are no certificates for symmetric keys.
auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM); auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
if (!algorithm) { if (!algorithm) {
LOG(ERROR) << __func__ << ": Unable to determine key algorithm."; LOG(ERROR) << __func__ << ": Unable to determine key algorithm.";
return V4_0_ErrorCode::UNKNOWN_ERROR; return KMV1::ErrorCode::UNKNOWN_ERROR;
} }
switch (*algorithm) { switch (*algorithm) {
case Algorithm::RSA: case Algorithm::RSA:
case Algorithm::EC: case Algorithm::EC:
break; break;
default: default:
return V4_0_ErrorCode::OK; return KMV1::ErrorCode::OK;
} }
// If attestation was requested, call and use attestKey. // If attestation was requested, call and use attestKey.
if (containsParam(keyParams, KMV1::TAG_ATTESTATION_CHALLENGE)) { if (containsParam(keyParams, KMV1::TAG_ATTESTATION_CHALLENGE)) {
auto legacyParams = convertKeyParametersToLegacy(keyParams); auto legacyParams = convertKeyParametersToLegacy(keyParams);
std::vector<Certificate> certs; std::vector<Certificate> certs;
V4_0_ErrorCode errorCode = V4_0_ErrorCode::OK; KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
auto result = mDevice->attestKey( auto result = mDevice->attestKey(
keyBlob, legacyParams, keyBlob, legacyParams,
[&](V4_0_ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) { [&](V4_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
errorCode = error; errorCode = convert(error);
for (const auto& cert : certChain) { for (const auto& cert : certChain) {
Certificate certificate; Certificate certificate;
certificate.encodedCertificate = cert; certificate.encodedCertificate = cert;
@ -736,9 +739,9 @@ KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
}); });
if (!result.isOk()) { if (!result.isOk()) {
LOG(ERROR) << __func__ << ": Call to attestKey failed."; 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 errorCode;
} }
return certs; return certs;
@ -746,8 +749,8 @@ KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
// makeCert // makeCert
auto certOrError = makeCert(mDevice, keyParams, keyBlob); auto certOrError = makeCert(mDevice, keyParams, keyBlob);
if (std::holds_alternative<V4_0_ErrorCode>(certOrError)) { if (std::holds_alternative<KMV1::ErrorCode>(certOrError)) {
return std::get<V4_0_ErrorCode>(certOrError); return std::get<KMV1::ErrorCode>(certOrError);
} }
auto cert = std::move(std::get<keystore::X509_Ptr>(certOrError)); auto cert = std::move(std::get<keystore::X509_Ptr>(certOrError));
@ -755,7 +758,7 @@ KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
auto error = keystore::setIssuer(&*cert, &*cert, false); auto error = keystore::setIssuer(&*cert, &*cert, false);
if (error) { if (error) {
LOG(ERROR) << __func__ << ": Set issuer failed."; LOG(ERROR) << __func__ << ": Set issuer failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR; return KMV1::ErrorCode::UNKNOWN_ERROR;
} }
// Signing // Signing
@ -780,7 +783,7 @@ KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
error = keystore::signCert(&*cert, pkey_ptr); error = keystore::signCert(&*cert, pkey_ptr);
if (error) { if (error) {
LOG(ERROR) << __func__ << ": signCert failed."; LOG(ERROR) << __func__ << ": signCert failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR; return KMV1::ErrorCode::UNKNOWN_ERROR;
} }
} }
@ -788,7 +791,7 @@ KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
auto encodedCertOrError = keystore::encodeCert(&*cert); auto encodedCertOrError = keystore::encodeCert(&*cert);
if (std::holds_alternative<keystore::CertUtilsError>(encodedCertOrError)) { if (std::holds_alternative<keystore::CertUtilsError>(encodedCertOrError)) {
LOG(ERROR) << __func__ << ": encodeCert failed."; LOG(ERROR) << __func__ << ": encodeCert failed.";
return V4_0_ErrorCode::UNKNOWN_ERROR; return KMV1::ErrorCode::UNKNOWN_ERROR;
} }
Certificate certificate{.encodedCertificate = Certificate certificate{.encodedCertificate =

View file

@ -18,6 +18,7 @@
#include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h> #include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h>
#include <aidl/android/hardware/security/keymint/BnKeyMintOperation.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/secureclock/BnSecureClock.h>
#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h> #include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h>
#include <aidl/android/security/compat/BnKeystoreCompatService.h> #include <aidl/android/security/compat/BnKeystoreCompatService.h>
@ -41,6 +42,7 @@ using ::aidl::android::hardware::security::keymint::KeyPurpose;
using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel; using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel;
using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode; using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
using ::aidl::android::hardware::security::keymint::IKeyMintDevice; 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::ISecureClock;
using ::aidl::android::hardware::security::secureclock::TimeStampToken; using ::aidl::android::hardware::security::secureclock::TimeStampToken;
using ::aidl::android::hardware::security::sharedsecret::ISharedSecret; using ::aidl::android::hardware::security::sharedsecret::ISharedSecret;
@ -112,13 +114,13 @@ class KeyMintDevice : public aidl::android::hardware::security::keymint::BnKeyMi
// These are public to allow testing code to use them directly. // These are public to allow testing code to use them directly.
// This class should not be used publicly anyway. // 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); getCertificate(const std::vector<KeyParameter>& keyParams, const std::vector<uint8_t>& keyBlob);
void setNumFreeSlots(uint8_t numFreeSlots); void setNumFreeSlots(uint8_t numFreeSlots);
private: 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); const std::vector<uint8_t>& keyBlob, X509* cert);
KeyMintSecurityLevel securityLevel_; KeyMintSecurityLevel securityLevel_;
}; };

View file

@ -16,6 +16,7 @@
#pragma once #pragma once
#include <aidl/android/hardware/security/keymint/ErrorCode.h>
#include <keymasterV4_1/keymaster_tags.h> #include <keymasterV4_1/keymaster_tags.h>
#include <keymint_support/keymint_tags.h> #include <keymint_support/keymint_tags.h>
@ -23,6 +24,159 @@ namespace V4_0 = ::android::hardware::keymaster::V4_0;
namespace V4_1 = ::android::hardware::keymaster::V4_1; namespace V4_1 = ::android::hardware::keymaster::V4_1;
namespace KMV1 = ::aidl::android::hardware::security::keymint; 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) { static std::optional<V4_0::KeyPurpose> convert(KMV1::KeyPurpose p) {
switch (p) { switch (p) {
case KMV1::KeyPurpose::ENCRYPT: case KMV1::KeyPurpose::ENCRYPT:

View file

@ -150,3 +150,84 @@ TEST(KmCompatTypeConversionTest, testKeyParameterConversion) {
TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_SECURE_ID); TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_SECURE_ID);
TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_VENDOR_PATCHLEVEL); 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);
}