Retry getKeyAttestationApplicationId when fails
We want to retry the command getKeyAttestationApplicationId
some number of times before we return a failure to the user.
Getting the attest app id can fail at times, but if we retry
it may succeed.
Test: atest keystore2_test
Test: atest CtsKeystoreTestCases
Bug: 238619180
Change-Id: I77e76c2f33f08c9214ea290284e75078e3b1eea1
diff --git a/keystore/Android.bp b/keystore/Android.bp
index c79d00b..2d78f33 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -20,14 +20,14 @@
sanitize: {
misc_undefined: [
- "signed-integer-overflow",
- "unsigned-integer-overflow",
- "shift",
- "integer-divide-by-zero",
- "implicit-unsigned-integer-truncation",
- // BUG: 123630767
- //"implicit-signed-integer-truncation",
- "implicit-integer-sign-change",
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ "shift",
+ "integer-divide-by-zero",
+ "implicit-unsigned-integer-truncation",
+ // BUG: 123630767
+ //"implicit-signed-integer-truncation",
+ "implicit-integer-sign-change",
],
},
@@ -66,7 +66,10 @@
// in Tag::ATTESTATION_APPLICATION_ID
cc_library {
name: "libkeystore-attestation-application-id",
- defaults: ["keystore_defaults"],
+ defaults: [
+ "keystore_defaults",
+ "keystore2_use_latest_aidl_ndk_shared",
+ ],
srcs: [
"keystore_attestation_id.cpp",
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 1534be1..d607fbf 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -29,6 +29,7 @@
#include <binder/Parcelable.h>
#include <binder/PersistableBundle.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
#include <android/security/keystore/BpKeyAttestationApplicationIdProvider.h>
#include <android/security/keystore/IKeyAttestationApplicationIdProvider.h>
#include <android/security/keystore/KeyAttestationApplicationId.h>
@@ -49,6 +50,8 @@
constexpr const char* kAttestationSystemPackageName = "AndroidSystem";
constexpr const char* kUnknownPackageName = "UnknownPackage";
+constexpr const size_t kMaxAttempts = 3;
+constexpr const unsigned long kRetryIntervalUsecs = 500000; // sleep for 500 ms
std::vector<uint8_t> signature2SHA256(const security::keystore::Signature& sig) {
std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
@@ -56,6 +59,7 @@
return digest_buffer;
}
+using ::aidl::android::system::keystore2::ResponseCode;
using ::android::security::keystore::BpKeyAttestationApplicationIdProvider;
class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
@@ -279,17 +283,31 @@
} else {
/* Get the attestation application ID from package manager */
auto& pm = KeyAttestationApplicationIdProvider::get();
- auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+ ::android::binder::Status status;
+
+ // Retry on failure if a service specific error code.
+ for (size_t attempt{0}; attempt < kMaxAttempts; ++attempt) {
+ status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+ if (status.isOk()) {
+ break;
+ } else if (status.exceptionCode() != binder::Status::EX_SERVICE_SPECIFIC) {
+ ALOGW("Retry: key attestation ID failed with service specific error: %s %d",
+ status.exceptionMessage().c_str(), status.serviceSpecificErrorCode());
+ usleep(kRetryIntervalUsecs);
+ } else {
+ ALOGW("Retry: key attestation ID failed with error: %s %d",
+ status.exceptionMessage().c_str(), status.exceptionCode());
+ usleep(kRetryIntervalUsecs);
+ }
+ }
+
// Package Manager call has failed, perform attestation but indicate that the
// caller is unknown.
if (!status.isOk()) {
ALOGW("package manager request for key attestation ID failed with: %s %d",
status.exceptionMessage().c_str(), status.exceptionCode());
- auto pinfo = KeyAttestationPackageInfo();
- pinfo.packageName = String16(kUnknownPackageName);
- pinfo.versionCode = 1;
- key_attestation_id.packageInfos.push_back(std::move(pinfo));
+ return int32_t(ResponseCode::GET_ATTESTATION_APPLICATION_ID_FAILED);
}
}
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 951acb5..1661f8e 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -443,17 +443,19 @@
// If there is an attestation challenge we need to get an application id.
if params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
- let aaid = {
- let _wp = self
- .watch("In KeystoreSecurityLevel::add_required_parameters calling: get_aaid");
- keystore2_aaid::get_aaid(uid)
- .map_err(|e| anyhow!(ks_err!("get_aaid returned status {}.", e)))
- }?;
-
- result.push(KeyParameter {
- tag: Tag::ATTESTATION_APPLICATION_ID,
- value: KeyParameterValue::Blob(aaid),
- });
+ let _wp =
+ self.watch("In KeystoreSecurityLevel::add_required_parameters calling: get_aaid");
+ match keystore2_aaid::get_aaid(uid) {
+ Ok(aaid_ok) => {
+ result.push(KeyParameter {
+ tag: Tag::ATTESTATION_APPLICATION_ID,
+ value: KeyParameterValue::Blob(aaid_ok),
+ });
+ }
+ Err(e) => {
+ return Err(anyhow!(e)).context(ks_err!("Attestation ID retrieval error."))
+ }
+ }
}
if params.iter().any(|kp| kp.tag == Tag::INCLUDE_UNIQUE_ID) {