From 926a6c032f4dcd14d8dbdcdfeea9446f52e89a7c Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Sat, 30 Jan 2021 22:33:11 -0800 Subject: [PATCH] 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 --- keystore2/src/km_compat/km_compat.cpp | 203 +++++++++--------- keystore2/src/km_compat/km_compat.h | 6 +- .../src/km_compat/km_compat_type_conversion.h | 154 +++++++++++++ .../km_compat/parameter_conversion_test.cpp | 81 +++++++ 4 files changed, 342 insertions(+), 102 deletions(-) diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp index a27bfd13..2273d73c 100644 --- a/keystore2/src/km_compat/km_compat.cpp +++ b/keystore2/src/km_compat/km_compat.cpp @@ -52,19 +52,23 @@ namespace KMV1 = ::aidl::android::hardware::security::keymint; // 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(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(status.getServiceSpecificError()); + return static_cast(status.getServiceSpecificError()); } 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; }); if (!result.isOk()) { - return ScopedAStatus::fromServiceSpecificError( - static_cast(ResponseCode::SYSTEM_ERROR)); + return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR); } return ScopedAStatus::ok(); } ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector& 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& 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& keyBlob, const V4_0_KeyCharacteristics& keyCharacteristics) { - errorCode = error; + errorCode = convert(error); out_creationResult->keyBlob = keyBlob; out_creationResult->keyCharacteristics = convertKeyCharacteristicsFromLegacy(securityLevel_, keyCharacteristics); @@ -201,12 +207,12 @@ ScopedAStatus KeyMintDevice::generateKey(const std::vector& in_key return ScopedAStatus::fromServiceSpecificError( static_cast(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(cert)) { - auto code = std::get(cert); + if (std::holds_alternative(cert)) { + auto code = std::get(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); } @@ -223,26 +229,25 @@ ScopedAStatus KeyMintDevice::importKey(const std::vector& in_inKey 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& 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(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(cert)) { - auto code = std::get(cert); + if (std::holds_alternative(cert)) { + auto code = std::get(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); } @@ -259,20 +264,19 @@ ScopedAStatus KeyMintDevice::importWrappedKey( const std::vector& 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& 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(ResponseCode::SYSTEM_ERROR)); + return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR); } return convertErrorCode(errorCode); } @@ -289,20 +293,25 @@ ScopedAStatus KeyMintDevice::upgradeKey(const std::vector& in_inKeyBlob *_aidl_return = upgradedKeyBlob; }); if (!result.isOk()) { - return ScopedAStatus::fromServiceSpecificError( - static_cast(ResponseCode::SYSTEM_ERROR)); + return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR); } return convertErrorCode(errorCode); } ScopedAStatus KeyMintDevice::deleteKey(const std::vector& 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. @@ -323,24 +332,21 @@ ScopedAStatus KeyMintDevice::begin(KeyPurpose in_inPurpose, 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& 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( 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(ResponseCode::SYSTEM_ERROR)); + errorCode = KMV1::ErrorCode::UNKNOWN_ERROR; } - if (errorCode != V4_0_ErrorCode::OK) { + if (errorCode != KMV1::ErrorCode::OK) { mOperationSlots.freeSlot(); } return convertErrorCode(errorCode); @@ -366,12 +372,12 @@ ScopedAStatus KeyMintOperation::update(const std::optional& i 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& outParams, const hidl_vec& output) { - errorCode = error; + errorCode = convert(error); out_outParams->emplace(); out_outParams->value().params = convertKeyParametersFromLegacy(outParams); out_output->emplace(); @@ -379,11 +385,9 @@ ScopedAStatus KeyMintOperation::update(const std::optional& i *_aidl_return = inputConsumed; }); if (!result.isOk()) { - mOperationSlot.freeSlot(); - return ScopedAStatus::fromServiceSpecificError( - static_cast(ResponseCode::SYSTEM_ERROR)); + errorCode = KMV1::ErrorCode::UNKNOWN_ERROR; } - if (errorCode != V4_0_ErrorCode::OK) { + if (errorCode != KMV1::ErrorCode::OK) { mOperationSlot.freeSlot(); } return convertErrorCode(errorCode); @@ -396,7 +400,7 @@ ScopedAStatus KeyMintOperation::finish(const std::optional& i const std::optional& in_inTimeStampToken, std::optional* out_outParams, std::vector* _aidl_return) { - V4_0_ErrorCode errorCode; + KMV1::ErrorCode errorCode; std::vector legacyParams; if (in_inParams.has_value()) { legacyParams = convertKeyParametersToLegacy(in_inParams.value().params); @@ -415,23 +419,25 @@ ScopedAStatus KeyMintOperation::finish(const std::optional& i mOperationHandle, legacyParams, input, signature, authToken, verificationToken, [&](V4_0_ErrorCode error, const hidl_vec& outParams, const hidl_vec& 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(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() { @@ -446,18 +452,17 @@ KeyMintOperation::~KeyMintOperation() { // 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(ResponseCode::SYSTEM_ERROR)); + errorCode = KMV1::ErrorCode::UNKNOWN_ERROR; } return convertErrorCode(errorCode); } @@ -465,17 +470,16 @@ ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToke // 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(ResponseCode::SYSTEM_ERROR)); + errorCode = KMV1::ErrorCode::UNKNOWN_ERROR; } return convertErrorCode(errorCode); } @@ -483,16 +487,15 @@ ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _a ScopedAStatus SharedSecret::computeSharedSecret(const std::vector& in_params, std::vector* _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& sharingCheck) { - errorCode = error; + errorCode = convert(error); *_aidl_return = sharingCheck; }); if (!result.isOk()) { - return ScopedAStatus::fromServiceSpecificError( - static_cast(ResponseCode::SYSTEM_ERROR)); + errorCode = KMV1::ErrorCode::UNKNOWN_ERROR; } return convertErrorCode(errorCode); } @@ -536,12 +539,12 @@ getMaximum(const std::vector& keyParams, T tag, return *bestSoFar; } -static std::variant +static std::variant makeCert(::android::sp mDevice, const std::vector& keyParams, const std::vector& keyBlob) { // Start generating the certificate. // Get public key for makeCert. - V4_0_ErrorCode errorCode; + KMV1::ErrorCode errorCode; std::vector key; static std::vector empty_vector; auto unwrapBlob = [&](auto b) -> const std::vector& { @@ -554,13 +557,13 @@ makeCert(::android::sp mDevice, const std::vector& keyP 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& 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. @@ -585,12 +588,12 @@ makeCert(::android::sp mDevice, const std::vector& keyP std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */); if (std::holds_alternative(certOrError)) { LOG(ERROR) << __func__ << ": Failed to make certificate"; - return V4_0_ErrorCode::UNKNOWN_ERROR; + return KMV1::ErrorCode::UNKNOWN_ERROR; } return std::move(std::get(certOrError)); } -static std::variant getKeystoreAlgorithm(Algorithm algorithm) { +static std::variant getKeystoreAlgorithm(Algorithm algorithm) { switch (algorithm) { case Algorithm::RSA: return keystore::Algo::RSA; @@ -598,11 +601,11 @@ static std::variant getKeystoreAlgorithm(Algorit 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 getKeystorePadding(PaddingMode padding) { +static std::variant getKeystorePadding(PaddingMode padding) { switch (padding) { case PaddingMode::RSA_PKCS1_1_5_SIGN: return keystore::Padding::PKCS1_5; @@ -613,7 +616,7 @@ static std::variant getKeystorePadding(Paddin } } -static std::variant getKeystoreDigest(Digest digest) { +static std::variant getKeystoreDigest(Digest digest) { switch (digest) { case Digest::SHA1: return keystore::Digest::SHA1; @@ -628,36 +631,36 @@ static std::variant getKeystoreDigest(Digest d return keystore::Digest::SHA512; default: LOG(ERROR) << __func__ << ": Unknown digest."; - return V4_0_ErrorCode::UNKNOWN_ERROR; + return KMV1::ErrorCode::UNKNOWN_ERROR; } } -std::optional +std::optional KeyMintDevice::signCertificate(const std::vector& keyParams, const std::vector& keyBlob, X509* cert) { auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM); auto algoOrError = getKeystoreAlgorithm(*algorithm); - if (std::holds_alternative(algoOrError)) { - return std::get(algoOrError); + if (std::holds_alternative(algoOrError)) { + return std::get(algoOrError); } auto algo = std::get(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(paddingOrError)) { - return std::get(paddingOrError); + if (std::holds_alternative(paddingOrError)) { + return std::get(paddingOrError); } auto padding = std::get(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(digestOrError)) { - return std::get(digestOrError); + if (std::holds_alternative(digestOrError)) { + return std::get(digestOrError); } auto digest = std::get(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) { @@ -694,40 +697,40 @@ KeyMintDevice::signCertificate(const std::vector& keyParams, 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, V4_0_ErrorCode> +std::variant, KMV1::ErrorCode> KeyMintDevice::getCertificate(const std::vector& keyParams, const std::vector& 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 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>& certChain) { - errorCode = error; + [&](V4_0::ErrorCode error, const hidl_vec>& certChain) { + errorCode = convert(error); for (const auto& cert : certChain) { Certificate certificate; certificate.encodedCertificate = cert; @@ -736,9 +739,9 @@ KeyMintDevice::getCertificate(const std::vector& keyParams, }); 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; @@ -746,8 +749,8 @@ KeyMintDevice::getCertificate(const std::vector& keyParams, // makeCert auto certOrError = makeCert(mDevice, keyParams, keyBlob); - if (std::holds_alternative(certOrError)) { - return std::get(certOrError); + if (std::holds_alternative(certOrError)) { + return std::get(certOrError); } auto cert = std::move(std::get(certOrError)); @@ -755,7 +758,7 @@ KeyMintDevice::getCertificate(const std::vector& keyParams, 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 @@ -780,7 +783,7 @@ KeyMintDevice::getCertificate(const std::vector& keyParams, error = keystore::signCert(&*cert, pkey_ptr); if (error) { 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& keyParams, auto encodedCertOrError = keystore::encodeCert(&*cert); if (std::holds_alternative(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 481481aa..5637b583 100644 --- a/keystore2/src/km_compat/km_compat.h +++ b/keystore2/src/km_compat/km_compat.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ using ::aidl::android::hardware::security::keymint::KeyPurpose; 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 @@ class KeyMintDevice : public aidl::android::hardware::security::keymint::BnKeyMi // These are public to allow testing code to use them directly. // This class should not be used publicly anyway. - std::variant, V4_0_ErrorCode> + std::variant, KMV1_ErrorCode> getCertificate(const std::vector& keyParams, const std::vector& keyBlob); void setNumFreeSlots(uint8_t numFreeSlots); private: - std::optional signCertificate(const std::vector& keyParams, + std::optional signCertificate(const std::vector& keyParams, const std::vector& 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 db9d2a41..df9c8624 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 #include #include @@ -23,6 +24,159 @@ namespace V4_0 = ::android::hardware::keymaster::V4_0; 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 convert(KMV1::KeyPurpose p) { switch (p) { case KMV1::KeyPurpose::ENCRYPT: diff --git a/keystore2/src/km_compat/parameter_conversion_test.cpp b/keystore2/src/km_compat/parameter_conversion_test.cpp index 41be0671..48af20c4 100644 --- a/keystore2/src/km_compat/parameter_conversion_test.cpp +++ b/keystore2/src/km_compat/parameter_conversion_test.cpp @@ -150,3 +150,84 @@ TEST(KmCompatTypeConversionTest, testKeyParameterConversion) { 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); +}