summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanis Danisevskis <jdanis@google.com>2018-11-15 01:19:10 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-11-15 01:19:10 +0000
commitadde739791ceb5761389d9762356c1674f1f169a (patch)
treec05f50e2bccaee4f24e90e425bfe686bf2e193dd
parent81c7e390e7abe4dfdc8ea8ae88c03259ea4d92be (diff)
parent5ec4c2aa2a3e87ebd83721fd0ed3c3d8656b9568 (diff)
downloadsecurity-android-o-mr1-iot-release-smart-display-r40.1J.tar.gz
* changes: Start keymaster workers on demand Multi-threaded keystore
-rw-r--r--keystore-engine/Android.mk2
-rw-r--r--keystore-engine/android_engine.cpp3
-rw-r--r--keystore-engine/keystore_backend_binder.cpp134
-rw-r--r--keystore/Android.bp11
-rw-r--r--keystore/KeyStore.cpp2
-rw-r--r--keystore/KeystoreArguments.cpp61
-rw-r--r--keystore/KeystoreResponse.cpp43
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl27
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl27
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl27
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl27
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl26
-rw-r--r--keystore/binder/android/security/keystore/IKeystoreService.aidl (renamed from keystore/binder/android/security/IKeystoreService.aidl)50
-rw-r--r--keystore/binder/android/security/keystore/KeystoreResponse.aidl (renamed from keystore/binder/android/security/KeystoreArguments.aidl)10
-rw-r--r--keystore/include/keystore/KeyCharacteristics.h4
-rw-r--r--keystore/include/keystore/KeymasterArguments.h10
-rw-r--r--keystore/include/keystore/KeymasterCertificateChain.h1
-rw-r--r--keystore/include/keystore/KeystoreArg.h42
-rw-r--r--keystore/include/keystore/KeystoreArguments.h42
-rw-r--r--keystore/include/keystore/KeystoreResponse.h62
-rw-r--r--keystore/include/keystore/keystore_client_impl.h5
-rw-r--r--keystore/include/keystore/keystore_promises.h72
-rw-r--r--keystore/key_store_service.cpp416
-rw-r--r--keystore/key_store_service.h93
-rw-r--r--keystore/keymaster_worker.cpp41
-rw-r--r--keystore/keymaster_worker.h1
-rw-r--r--keystore/keystore_aidl_hidl_marshalling_utils.cpp7
-rw-r--r--keystore/keystore_aidl_hidl_marshalling_utils.h2
-rw-r--r--keystore/keystore_cli.cpp4
-rw-r--r--keystore/keystore_cli_v2.cpp4
-rw-r--r--keystore/keystore_client_impl.cpp140
-rw-r--r--keystore/keystore_get.cpp6
-rw-r--r--keystore/keystore_main.cpp2
-rw-r--r--keystore/keystore_utils.cpp3
-rw-r--r--keystore/legacy_keymaster_device_wrapper.cpp19
35 files changed, 832 insertions, 594 deletions
diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index e65e011d..e182dbdd 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -24,6 +24,7 @@ LOCAL_SRC_FILES := \
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
+LOCAL_CPPFLAGS += -std=c++17
LOCAL_SHARED_LIBRARIES += \
libbinder \
@@ -53,6 +54,7 @@ LOCAL_SRC_FILES := \
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror -DBACKEND_WIFI_HIDL
+LOCAL_CPPFLAGS += -std=c++17
LOCAL_SHARED_LIBRARIES += \
android.system.wifi.keystore@1.0 \
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index fba2583d..856194d0 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -80,8 +80,7 @@ void key_id_free(void* /* parent */,
* the argument on failure. This means we need to tell our scoped pointers when
* we've transferred ownership, without triggering a warning by not using the
* result of release(). */
-#define OWNERSHIP_TRANSFERRED(obj) \
- typeof ((obj).release()) _dummy __attribute__((unused)) = (obj).release()
+#define OWNERSHIP_TRANSFERRED(obj) auto _dummy __attribute__((unused)) = (obj).release()
const char* rsa_get_key_id(const RSA* rsa);
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
index cd407c84..0e38b50e 100644
--- a/keystore-engine/keystore_backend_binder.cpp
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -23,18 +23,22 @@
#include "keystore_backend_binder.h"
#include <android-base/logging.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IServiceManager.h>
#include <keystore/KeyCharacteristics.h>
#include <keystore/KeymasterArguments.h>
#include <keystore/KeymasterBlob.h>
+#include <keystore/KeystoreResponse.h>
#include <keystore/OperationResult.h>
#include <keystore/keymaster_types.h>
#include <keystore/keystore.h>
#include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_promises.h>
#include <keystore/keystore_return_types.h>
-using android::security::IKeystoreService;
+#include <future>
+
+using android::security::keystore::IKeystoreService;
using namespace android;
using keystore::hidl_vec;
@@ -60,7 +64,13 @@ using KSReturn = keystore::KeyStoreNativeReturnCode;
namespace {
const char keystore_service_name[] = "android.security.keystore";
constexpr int32_t UID_SELF = -1;
-};
+
+using keystore::KeyCharacteristicsPromise;
+using keystore::KeystoreExportPromise;
+using keystore::KeystoreResponsePromise;
+using keystore::OperationResultPromise;
+
+} // namespace
#define AT __func__ << ":" << __LINE__ << " "
@@ -88,20 +98,29 @@ int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_
return -1;
}
- KeyCharacteristics keyCharacteristics;
String16 key_name16(key_id);
- int32_t aidl_result;
- auto binder_result = service->getKeyCharacteristics(
- key_name16, KeymasterBlob(), KeymasterBlob(), UID_SELF, &keyCharacteristics, &aidl_result);
+ int32_t error_code;
+ android::sp<KeyCharacteristicsPromise> kc_promise(new KeyCharacteristicsPromise);
+ auto kc_future = kc_promise->get_future();
+ auto binder_result = service->getKeyCharacteristics(kc_promise, key_name16, KeymasterBlob(),
+ KeymasterBlob(), UID_SELF, &error_code);
if (!binder_result.isOk()) {
LOG(ERROR) << AT << "communication error while calling keystore";
return -1;
}
- if (KSReturn(aidl_result).isOk()) {
- LOG(ERROR) << AT << "getKeyCharacteristics failed: " << aidl_result;
+ if (KSReturn(error_code).isOk()) {
+ LOG(ERROR) << AT << "getKeyCharacteristics failed: " << error_code;
+ return -1;
+ }
+
+ auto [km_response, characteristics] = kc_future.get();
+
+ if (KSReturn(km_response.response_code()).isOk()) {
+ LOG(ERROR) << AT << "getKeyCharacteristics failed: " << km_response.response_code();
+ return -1;
}
- auto algorithm = getKeyAlgoritmFromKeyCharacteristics(keyCharacteristics);
+ auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
if (!algorithm.isOk()) {
LOG(ERROR) << AT << "could not get algorithm from key characteristics";
return -1;
@@ -113,14 +132,23 @@ int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_
params[2] = Authorization(TAG_ALGORITHM, algorithm.value());
android::sp<android::IBinder> token(new android::BBinder);
- OperationResult result;
- binder_result = service->begin(token, key_name16, (int)KeyPurpose::SIGN, true /*pruneable*/,
- KeymasterArguments(params), std::vector<uint8_t>() /* entropy */,
- UID_SELF, &result);
+ sp<OperationResultPromise> promise(new OperationResultPromise());
+ auto future = promise->get_future();
+ binder_result = service->begin(promise, token, key_name16, (int)KeyPurpose::SIGN,
+ true /*pruneable*/, KeymasterArguments(params),
+ std::vector<uint8_t>() /* entropy */, UID_SELF, &error_code);
if (!binder_result.isOk()) {
LOG(ERROR) << AT << "communication error while calling keystore";
return -1;
}
+
+ keystore::KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) {
+ LOG(ERROR) << AT << "Keystore begin returned: " << error_code;
+ return -1;
+ }
+ OperationResult result = future.get();
+
if (!result.resultCode.isOk()) {
LOG(ERROR) << AT << "begin failed: " << int32_t(result.resultCode);
return -1;
@@ -128,32 +156,71 @@ int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_
auto handle = std::move(result.token);
do {
- binder_result = service->update(handle, KeymasterArguments(params),
- std::vector<uint8_t>(in, in + len), &result);
+ future = {};
+ promise = new OperationResultPromise();
+ future = promise->get_future();
+ binder_result = service->update(promise, handle, KeymasterArguments(params),
+ std::vector<uint8_t>(in, in + len), &error_code);
if (!binder_result.isOk()) {
LOG(ERROR) << AT << "communication error while calling keystore";
return -1;
}
+
+ rc = keystore::KeyStoreNativeReturnCode(error_code);
+ if (!rc.isOk()) {
+ LOG(ERROR) << AT << "Keystore update returned: " << error_code;
+ return -1;
+ }
+ result = future.get();
+
if (!result.resultCode.isOk()) {
LOG(ERROR) << AT << "update failed: " << int32_t(result.resultCode);
return -1;
}
+
if (result.inputConsumed > len) {
LOG(ERROR) << AT << "update consumed more data than provided";
- service->abort(handle, &aidl_result);
+ sp<KeystoreResponsePromise> abortPromise(new KeystoreResponsePromise);
+ auto abortFuture = abortPromise->get_future();
+ binder_result = service->abort(abortPromise, handle, &error_code);
+ if (!binder_result.isOk()) {
+ LOG(ERROR) << AT << "communication error while calling keystore";
+ return -1;
+ }
+ // This is mainly for logging since we already failed.
+ // But if abort returned OK we have to wait untill abort calls the callback
+ // hence the call to abortFuture.get().
+ if (!KSReturn(error_code).isOk()) {
+ LOG(ERROR) << AT << "abort failed: " << error_code;
+ } else if (!(rc = KSReturn(abortFuture.get().response_code())).isOk()) {
+ LOG(ERROR) << AT << "abort failed: " << int32_t(rc);
+ }
return -1;
}
len -= result.inputConsumed;
in += result.inputConsumed;
} while (len > 0);
- binder_result =
- service->finish(handle, KeymasterArguments(params), std::vector<uint8_t>() /* signature */,
- std::vector<uint8_t>() /* entropy */, &result);
+ future = {};
+ promise = new OperationResultPromise();
+ future = promise->get_future();
+
+ binder_result = service->finish(promise, handle, KeymasterArguments(params),
+ std::vector<uint8_t>() /* signature */,
+ std::vector<uint8_t>() /* entropy */, &error_code);
+
if (!binder_result.isOk()) {
LOG(ERROR) << AT << "communication error while calling keystore";
return -1;
}
+
+ rc = keystore::KeyStoreNativeReturnCode(error_code);
+ if (!rc.isOk()) {
+ LOG(ERROR) << AT << "Keystore finish returned: " << error_code;
+ return -1;
+ }
+ result = future.get();
+
if (!result.resultCode.isOk()) {
LOG(ERROR) << AT << "finish failed: " << int32_t(result.resultCode);
return -1;
@@ -180,25 +247,34 @@ int32_t KeystoreBackendBinder::get_pubkey(const char* key_id, uint8_t** pubkey,
return -1;
}
- ExportResult result;
- auto binder_result = service->exportKey(String16(key_id), static_cast<int32_t>(KeyFormat::X509),
- KeymasterBlob() /* clientId */,
- KeymasterBlob() /* appData */, UID_SELF, &result);
+ int32_t error_code;
+ android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
+ auto future = promise->get_future();
+ auto binder_result = service->exportKey(
+ promise, String16(key_id), static_cast<int32_t>(KeyFormat::X509),
+ KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &error_code);
if (!binder_result.isOk()) {
LOG(ERROR) << AT << "communication error while calling keystore";
return -1;
}
- if (!result.resultCode.isOk()) {
- LOG(ERROR) << AT << "exportKey failed: " << int32_t(result.resultCode);
+
+ KSReturn rc(error_code);
+ if (!rc.isOk()) {
+ LOG(ERROR) << AT << "exportKey failed: " << error_code;
+ return -1;
+ }
+
+ auto export_result = future.get();
+ if (!export_result.resultCode.isOk()) {
+ LOG(ERROR) << AT << "exportKey failed: " << int32_t(export_result.resultCode);
return -1;
}
- hidl_vec<uint8_t> reply_hidl(result.exportData);
if (pubkey_len) {
- *pubkey_len = reply_hidl.size();
+ *pubkey_len = export_result.exportData.size();
}
if (pubkey) {
- *pubkey = reply_hidl.releaseData();
+ *pubkey = export_result.exportData.releaseData();
}
return 0;
}
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 1168e909..295d6055 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -139,10 +139,10 @@ cc_library_shared {
"KeyAttestationApplicationId.cpp",
"KeyAttestationPackageInfo.cpp",
"KeymasterArguments.cpp",
- "KeystoreArguments.cpp",
+ "keystore_aidl_hidl_marshalling_utils.cpp",
+ "KeystoreResponse.cpp",
"OperationResult.cpp",
"Signature.cpp",
- "keystore_aidl_hidl_marshalling_utils.cpp",
],
shared_libs: [
"android.hardware.keymaster@4.0",
@@ -269,7 +269,12 @@ filegroup {
name: "keystore_aidl",
srcs: [
"binder/android/security/IConfirmationPromptCallback.aidl",
- "binder/android/security/IKeystoreService.aidl",
+ "binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl",
+ "binder/android/security/keystore/IKeystoreExportKeyCallback.aidl",
+ "binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl",
+ "binder/android/security/keystore/IKeystoreOperationResultCallback.aidl",
+ "binder/android/security/keystore/IKeystoreResponseCallback.aidl",
+ "binder/android/security/keystore/IKeystoreService.aidl",
],
path: "binder",
}
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index 8c4844fd..75302435 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -28,7 +28,7 @@
#include <android-base/scopeguard.h>
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <log/log_event_list.h>
#include <private/android_logger.h>
diff --git a/keystore/KeystoreArguments.cpp b/keystore/KeystoreArguments.cpp
deleted file mode 100644
index 6b29e786..00000000
--- a/keystore/KeystoreArguments.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include "include/keystore/KeystoreArguments.h"
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-
-using ::android::security::KeystoreArg;
-using ::android::security::KeystoreArguments;
-
-const ssize_t MAX_GENERATE_ARGS = 3;
-status_t KeystoreArguments::readFromParcel(const android::Parcel* in) {
- ssize_t numArgs = in->readInt32();
- if (numArgs > MAX_GENERATE_ARGS) {
- return BAD_VALUE;
- }
- if (numArgs > 0) {
- for (size_t i = 0; i < static_cast<size_t>(numArgs); i++) {
- ssize_t inSize = in->readInt32();
- if (inSize >= 0 && static_cast<size_t>(inSize) <= in->dataAvail()) {
- sp<KeystoreArg> arg = new KeystoreArg(in->readInplace(inSize), inSize);
- args.push_back(arg);
- } else {
- args.push_back(nullptr);
- }
- }
- }
- return OK;
-};
-
-status_t KeystoreArguments::writeToParcel(android::Parcel* out) const {
- out->writeInt32(args.size());
- for (sp<KeystoreArg> item : args) {
- size_t keyLength = item->size();
- out->writeInt32(keyLength);
- void* buf = out->writeInplace(keyLength);
- memcpy(buf, item->data(), keyLength);
- }
- return OK;
-}
-
-} // namespace security
-} // namespace android
diff --git a/keystore/KeystoreResponse.cpp b/keystore/KeystoreResponse.cpp
new file mode 100644
index 00000000..c46973a5
--- /dev/null
+++ b/keystore/KeystoreResponse.cpp
@@ -0,0 +1,43 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <binder/Parcel.h>
+#include <keystore/keymaster_types.h>
+#include <utility>
+#include <utils/String16.h>
+
+#include "include/keystore/KeystoreResponse.h"
+
+namespace android {
+namespace security {
+namespace keystore {
+
+status_t KeystoreResponse::readFromParcel(const Parcel* in) {
+ auto rc = in->readInt32(&response_code_);
+ if (rc != NO_ERROR) return rc;
+ return in->readString16(&error_msg_);
+}
+
+status_t KeystoreResponse::writeToParcel(Parcel* out) const {
+ auto rc = out->writeInt32(response_code_);
+ if (rc != NO_ERROR) return rc;
+ return out->writeString16(error_msg_);
+}
+
+} // namespace keystore
+} // namespace security
+} // namespace android
diff --git a/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
new file mode 100644
index 00000000..dca928d9
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.KeymasterCertificateChain;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreCertificateChainCallback {
+ void onFinished(in KeystoreResponse response, in KeymasterCertificateChain chain);
+} \ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
new file mode 100644
index 00000000..e42e9274
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.ExportResult;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreExportKeyCallback {
+ void onFinished(in ExportResult result);
+} \ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
new file mode 100644
index 00000000..e1f0ffed
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.KeyCharacteristics;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreKeyCharacteristicsCallback {
+ void onFinished(in KeystoreResponse response, in KeyCharacteristics charactersistics);
+} \ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
new file mode 100644
index 00000000..0a515113
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeystoreResponse;
+import android.security.keymaster.OperationResult;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreOperationResultCallback {
+ void onFinished(in OperationResult result);
+} \ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
new file mode 100644
index 00000000..912e6054
--- /dev/null
+++ b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeystoreResponse;
+
+/**
+ * @hide
+ */
+oneway interface IKeystoreResponseCallback {
+ void onFinished(in KeystoreResponse response);
+} \ No newline at end of file
diff --git a/keystore/binder/android/security/IKeystoreService.aidl b/keystore/binder/android/security/keystore/IKeystoreService.aidl
index c490eda8..a7601388 100644
--- a/keystore/binder/android/security/IKeystoreService.aidl
+++ b/keystore/binder/android/security/keystore/IKeystoreService.aidl
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2015, The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,18 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterCertificateChain;
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.OperationResult;
-import android.security.KeystoreArguments;
+import android.security.keystore.IKeystoreResponseCallback;
+import android.security.keystore.IKeystoreKeyCharacteristicsCallback;
+import android.security.keystore.IKeystoreExportKeyCallback;
+import android.security.keystore.IKeystoreOperationResultCallback;
+import android.security.keystore.IKeystoreCertificateChainCallback;
/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
* @hide
*/
interface IKeystoreService {
@@ -48,32 +46,30 @@ interface IKeystoreService {
int is_hardware_backed(String string);
int clear_uid(long uid);
- // Keymaster 0.4 methods
- int addRngEntropy(in byte[] data, int flags);
- int generateKey(String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
- int flags, out KeyCharacteristics characteristics);
- int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appData,
- int uid, out KeyCharacteristics characteristics);
- int importKey(String alias, in KeymasterArguments arguments, int format,
- in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
- ExportResult exportKey(String alias, int format, in KeymasterBlob clientId,
+ int addRngEntropy(IKeystoreResponseCallback cb, in byte[] data, int flags);
+ int generateKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
+ int flags);
+ int getKeyCharacteristics (IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterBlob clientId, in KeymasterBlob appData,
+ int uid);
+ int importKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, int format,
+ in byte[] keyData, int uid, int flags);
+ int exportKey(IKeystoreExportKeyCallback cb, String alias, int format, in KeymasterBlob clientId,
in KeymasterBlob appData, int uid);
- OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
+ int begin(in IKeystoreOperationResultCallback cb, IBinder appToken, String alias, int purpose, boolean pruneable,
in KeymasterArguments params, in byte[] entropy, int uid);
- OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
- OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature,
+ int update(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] input);
+ int finish(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] signature,
in byte[] entropy);
- int abort(IBinder handle);
+ int abort(in IKeystoreResponseCallback cb, IBinder token);
int addAuthToken(in byte[] authToken);
int onUserAdded(int userId, int parentId);
int onUserRemoved(int userId);
- int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);
- int attestDeviceIds(in KeymasterArguments params, out KeymasterCertificateChain chain);
+ int attestKey(in IKeystoreCertificateChainCallback cb, String alias, in KeymasterArguments params);
+ int attestDeviceIds(in IKeystoreCertificateChainCallback cb, in KeymasterArguments params);
int onDeviceOffBody();
- int importWrappedKey(in String wrappedKeyAlias, in byte[] wrappedKey,
+ int importWrappedKey(in IKeystoreKeyCharacteristicsCallback cb, String wrappedKeyAlias, in byte[] wrappedKey,
in String wrappingKeyAlias, in byte[] maskingKey, in KeymasterArguments arguments,
- in long rootSid, in long fingerprintSid,
- out KeyCharacteristics characteristics);
+ in long rootSid, in long fingerprintSid);
int presentConfirmationPrompt(IBinder listener, String promptText, in byte[] extraData,
in String locale, in int uiOptionsAsFlags);
int cancelConfirmationPrompt(IBinder listener);
diff --git a/keystore/binder/android/security/KeystoreArguments.aidl b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
index dc8ed501..128b4569 100644
--- a/keystore/binder/android/security/KeystoreArguments.aidl
+++ b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2015, The Android Open Source Project
+/*
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
/* @hide */
-parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h";
+parcelable KeystoreResponse cpp_header "keystore/KeystoreResponse.h";
diff --git a/keystore/include/keystore/KeyCharacteristics.h b/keystore/include/keystore/KeyCharacteristics.h
index 33c5c3a6..40d495c6 100644
--- a/keystore/include/keystore/KeyCharacteristics.h
+++ b/keystore/include/keystore/KeyCharacteristics.h
@@ -27,11 +27,11 @@ namespace keymaster {
// Parcelable version of keystore::KeyCharacteristics
struct KeyCharacteristics : public ::android::Parcelable {
KeyCharacteristics(){};
- KeyCharacteristics(keystore::KeyCharacteristics&& other) {
+ KeyCharacteristics(::keystore::KeyCharacteristics&& other) {
softwareEnforced = std::move(other.softwareEnforced);
hardwareEnforced = std::move(other.hardwareEnforced);
}
- explicit KeyCharacteristics(const keystore::KeyCharacteristics& other) {
+ explicit KeyCharacteristics(const ::keystore::KeyCharacteristics& other) {
softwareEnforced = KeymasterArguments(other.softwareEnforced);
hardwareEnforced = KeymasterArguments(other.hardwareEnforced);
}
diff --git a/keystore/include/keystore/KeymasterArguments.h b/keystore/include/keystore/KeymasterArguments.h
index fb35ee7b..b453b113 100644
--- a/keystore/include/keystore/KeymasterArguments.h
+++ b/keystore/include/keystore/KeymasterArguments.h
@@ -26,16 +26,18 @@ namespace keymaster {
// struct for serializing/deserializing a list of KeyParameters
struct KeymasterArguments : public Parcelable {
KeymasterArguments(){};
- KeymasterArguments(hardware::hidl_vec<keystore::KeyParameter>&& other);
- explicit KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other);
+ KeymasterArguments(hardware::hidl_vec<::keystore::KeyParameter>&& other);
+ explicit KeymasterArguments(const hardware::hidl_vec<::keystore::KeyParameter>& other);
status_t readFromParcel(const Parcel* in) override;
status_t writeToParcel(Parcel* out) const override;
- const inline hardware::hidl_vec<keystore::KeyParameter>& getParameters() const { return data_; }
+ const inline hardware::hidl_vec<::keystore::KeyParameter>& getParameters() const {
+ return data_;
+ }
private:
- hardware::hidl_vec<keystore::KeyParameter> data_;
+ hardware::hidl_vec<::keystore::KeyParameter> data_;
};
} // namespace keymaster
diff --git a/keystore/include/keystore/KeymasterCertificateChain.h b/keystore/include/keystore/KeymasterCertificateChain.h
index 132862c3..f251d084 100644
--- a/keystore/include/keystore/KeymasterCertificateChain.h
+++ b/keystore/include/keystore/KeymasterCertificateChain.h
@@ -16,6 +16,7 @@
#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
#include <binder/Parcelable.h>
+#include <keystore/keymaster_types.h>
namespace android {
namespace security {
diff --git a/keystore/include/keystore/KeystoreArg.h b/keystore/include/keystore/KeystoreArg.h
deleted file mode 100644
index a5e68f2b..00000000
--- a/keystore/include/keystore/KeystoreArg.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace security {
-
-// Simple pair of generic pointer and length of corresponding data structure.
-class KeystoreArg : public RefBase {
- public:
- KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
- ~KeystoreArg() {}
-
- const void* data() const { return mData; }
- size_t size() const { return mSize; }
-
- private:
- const void* mData; // provider of the data must handle memory clean-up.
- size_t mSize;
-};
-
-} // namespace security
-} // namespace android
-
-#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
diff --git a/keystore/include/keystore/KeystoreArguments.h b/keystore/include/keystore/KeystoreArguments.h
deleted file mode 100644
index c0a8b0a2..00000000
--- a/keystore/include/keystore/KeystoreArguments.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
-
-#include <binder/Parcelable.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-#include "KeystoreArg.h"
-#include "keystore_return_types.h"
-
-namespace android {
-namespace security {
-
-// Parcelable KeystoreArguments.java which simply holds byte[][].
-struct KeystoreArguments : public ::android::Parcelable, public RefBase {
- status_t readFromParcel(const Parcel* in) override;
- status_t writeToParcel(Parcel* out) const override;
-
- const Vector<sp<KeystoreArg>>& getArguments() const { return args; }
-
- private:
- Vector<sp<KeystoreArg>> args;
-};
-
-} // namespace security
-} // namespace android
-
-#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
diff --git a/keystore/include/keystore/KeystoreResponse.h b/keystore/include/keystore/KeystoreResponse.h
new file mode 100644
index 00000000..f8925851
--- /dev/null
+++ b/keystore/include/keystore/KeystoreResponse.h
@@ -0,0 +1,62 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_RESPONSE_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_RESPONSE_H_
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <utils/String8.h>
+
+#include "keystore_return_types.h"
+
+namespace android {
+namespace security {
+namespace keystore {
+
+// struct for holding response code and optionally an error message for keystore
+// AIDL callbacks
+struct KeystoreResponse : public ::android::Parcelable {
+ public:
+ KeystoreResponse() = default;
+ explicit KeystoreResponse(const int response_code, const String16& error_msg)
+ : response_code_(response_code), error_msg_(std::make_unique<String16>(error_msg)) {}
+ explicit KeystoreResponse(const int response_code)
+ : response_code_(response_code), error_msg_() {}
+ KeystoreResponse(const ::keystore::KeyStoreServiceReturnCode& rc)
+ : response_code_(int32_t(rc)), error_msg_() {}
+ KeystoreResponse(const KeystoreResponse& other)
+ : response_code_(other.response_code_), error_msg_() {
+ if (other.error_msg_) {
+ error_msg_ = std::make_unique<String16>(*other.error_msg_);
+ }
+ }
+ KeystoreResponse(KeystoreResponse&& other) = default;
+
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ int response_code() const { return response_code_; }
+ const String16* error_msg() const { return error_msg_.get(); }
+
+ private:
+ int response_code_;
+ std::unique_ptr<String16> error_msg_;
+};
+
+} // namespace keystore
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_RESPONSE_H_
diff --git a/keystore/include/keystore/keystore_client_impl.h b/keystore/include/keystore/keystore_client_impl.h
index 9edd0824..0bcef98c 100644
--- a/keystore/include/keystore/keystore_client_impl.h
+++ b/keystore/include/keystore/keystore_client_impl.h
@@ -17,11 +17,12 @@
#include "keystore_client.h"
+#include <future>
#include <map>
#include <string>
#include <vector>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <utils/StrongPointer.h>
@@ -109,7 +110,7 @@ class KeystoreClientImpl : public KeystoreClient {
android::sp<android::IServiceManager> service_manager_;
android::sp<android::IBinder> keystore_binder_;
- android::sp<android::security::IKeystoreService> keystore_;
+ android::sp<android::security::keystore::IKeystoreService> keystore_;
uint64_t next_virtual_handle_ = 1;
std::map<uint64_t, android::sp<android::IBinder>> active_operations_;
diff --git a/keystore/include/keystore/keystore_promises.h b/keystore/include/keystore/keystore_promises.h
new file mode 100644
index 00000000..3d45016e
--- /dev/null
+++ b/keystore/include/keystore/keystore_promises.h
@@ -0,0 +1,72 @@
+/*
+**
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_PROMISES_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_PROMISES_H_
+
+#include <android/security/keystore/BnKeystoreCertificateChainCallback.h>
+#include <android/security/keystore/BnKeystoreExportKeyCallback.h>
+#include <android/security/keystore/BnKeystoreKeyCharacteristicsCallback.h>
+#include <android/security/keystore/BnKeystoreOperationResultCallback.h>
+#include <android/security/keystore/BnKeystoreResponseCallback.h>
+#include <future>
+
+namespace keystore {
+
+template <typename BnInterface, typename Result>
+class CallbackPromise : public BnInterface, public std::promise<Result> {
+ public:
+ ::android::binder::Status onFinished(const Result& result) override {
+ this->set_value(result);
+ return ::android::binder::Status::ok();
+ }
+};
+
+template <typename BnInterface, typename... Results>
+class CallbackPromise<BnInterface, std::tuple<Results...>>
+ : public BnInterface, public std::promise<std::tuple<Results...>> {
+ public:
+ ::android::binder::Status onFinished(const Results&... results) override {
+ this->set_value({results...});
+ return ::android::binder::Status::ok();
+ }
+};
+
+using OperationResultPromise =
+ CallbackPromise<::android::security::keystore::BnKeystoreOperationResultCallback,
+ ::android::security::keymaster::OperationResult>;
+
+using KeystoreResponsePromise =
+ CallbackPromise<::android::security::keystore::BnKeystoreResponseCallback,
+ ::android::security::keystore::KeystoreResponse>;
+
+using KeyCharacteristicsPromise =
+ CallbackPromise<::android::security::keystore::BnKeystoreKeyCharacteristicsCallback,
+ std::tuple<::android::security::keystore::KeystoreResponse,
+ ::android::security::keymaster::KeyCharacteristics>>;
+using KeystoreExportPromise =
+ CallbackPromise<::android::security::keystore::BnKeystoreExportKeyCallback,
+ ::android::security::keymaster::ExportResult>;
+
+using KeyCertChainPromise =
+ CallbackPromise<::android::security::keystore::BnKeystoreCertificateChainCallback,
+ std::tuple<::android::security::keystore::KeystoreResponse,
+ ::android::security::keymaster::KeymasterCertificateChain>>;
+
+} // namespace keystore
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_PROMISES_H_
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 7ce58ca9..2f07fbf4 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -17,7 +17,6 @@
#define LOG_TAG "keystore"
#include "key_store_service.h"
-#include "include/keystore/KeystoreArg.h"
#include <fcntl.h>
#include <sys/stat.h>
@@ -57,7 +56,6 @@ using namespace android;
namespace {
using ::android::binder::Status;
-using android::security::KeystoreArg;
using android::security::keymaster::ExportResult;
using android::security::keymaster::KeymasterArguments;
using android::security::keymaster::KeymasterBlob;
@@ -65,6 +63,9 @@ using android::security::keymaster::KeymasterCertificateChain;
using android::security::keymaster::operationFailed;
using android::security::keymaster::OperationResult;
using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
+using ::android::security::keystore::IKeystoreOperationResultCallback;
+using ::android::security::keystore::IKeystoreResponseCallback;
+using ::android::security::keystore::KeystoreResponse;
constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
const char* kTimestampFilePath = "timestamp";
@@ -82,6 +83,9 @@ bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
[&](const KeyParameter& param) { return param.tag == tag; });
}
+#define AIDL_RETURN(rc) \
+ (*_aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(rc)), Status::ok())
+
std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
struct stat sbuf;
if (stat(kTimestampFilePath, &sbuf) == 0) {
@@ -545,113 +549,93 @@ Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* aidl_return) {
return Status::ok();
}
-Status KeyStoreService::addRngEntropy(const ::std::vector<uint8_t>& entropy, int32_t flags,
- int32_t* aidl_return) {
+Status KeyStoreService::addRngEntropy(
+ const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+ const ::std::vector<uint8_t>& entropy, int32_t flags, int32_t* _aidl_return) {
auto device = mKeyStore->getDevice(flagsToSecurityLevel(flags));
if (!device) {
- *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
}
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
- device->addRngEntropy(
- entropy, [&](Return<ErrorCode> rc) { resultPromise.set_value(KS_HANDLE_HIDL_ERROR(rc)); });
- resultFuture.wait();
- *aidl_return = int32_t(resultFuture.get());
- return Status::ok();
+ device->addRngEntropy(entropy, [cb](Return<ErrorCode> rc) {
+ cb->onFinished(KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(rc)));
+ });
+
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status
-KeyStoreService::generateKey(const String16& name, const KeymasterArguments& params,
- const ::std::vector<uint8_t>& entropy, int uid, int flags,
- android::security::keymaster::KeyCharacteristics* outCharacteristics,
- int32_t* aidl_return) {
+Status KeyStoreService::generateKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+ const String16& name, const KeymasterArguments& params, const ::std::vector<uint8_t>& entropy,
+ int uid, int flags, int32_t* _aidl_return) {
// TODO(jbires): remove this getCallingUid call upon implementation of b/25646100
uid_t originalUid = IPCThreadState::self()->getCallingUid();
uid = getEffectiveUid(uid);
auto logOnScopeExit = android::base::make_scope_guard([&] {
if (__android_log_security()) {
android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
- << int32_t(*aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
+ << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
<< String8(name) << int32_t(uid) << LOG_ID_SECURITY;
}
});
KeyStoreServiceReturnCode rc =
checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!rc.isOk()) {
- *aidl_return = static_cast<int32_t>(rc);
- return Status::ok();
+ return AIDL_RETURN(rc);
}
if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
- *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
if (containsTag(params.getParameters(), Tag::INCLUDE_UNIQUE_ID)) {
// TODO(jbires): remove uid checking upon implementation of b/25646100
if (!checkBinderPermission(P_GEN_UNIQUE_ID) ||
originalUid != IPCThreadState::self()->getCallingUid()) {
- *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
}
SecurityLevel securityLevel = flagsToSecurityLevel(flags);
auto dev = mKeyStore->getDevice(securityLevel);
if (!dev) {
- *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
}
String8 name8(name);
auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
if (!lockedEntry) {
- *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
}
logOnScopeExit.Disable();
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
+ dev->generateKey(
+ std::move(lockedEntry), params.getParameters(), entropy, flags,
+ [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+ if (__android_log_security()) {
+ android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
+ << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
+ }
+ cb->onFinished(rc,
+ android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+ });
- dev->generateKey(std::move(lockedEntry), params.getParameters(), entropy, flags,
- [&, uid](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
- if (outCharacteristics && rc.isOk()) {
- *outCharacteristics = android::security::keymaster::KeyCharacteristics(
- keyCharacteristics);
- }
- if (__android_log_security()) {
- android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
- << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
- }
- resultPromise.set_value(rc);
- });
-
- resultFuture.wait();
- *aidl_return = int32_t(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
Status KeyStoreService::getKeyCharacteristics(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
const String16& name, const ::android::security::keymaster::KeymasterBlob& clientId,
const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
- ::android::security::keymaster::KeyCharacteristics* outCharacteristics, int32_t* aidl_return) {
- if (!outCharacteristics) {
- *aidl_return =
- static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::UNEXPECTED_NULL_POINTER));
- return Status::ok();
- }
+ int32_t* _aidl_return) {
uid_t targetUid = getEffectiveUid(uid);
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!is_granted_to(callingUid, targetUid)) {
ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
targetUid);
- *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
String8 name8(name);
@@ -665,47 +649,37 @@ Status KeyStoreService::getKeyCharacteristics(
mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
if (rc != ResponseCode::NO_ERROR) {
- *aidl_return = static_cast<int32_t>(rc);
- return Status::ok();
+ return AIDL_RETURN(rc);
}
auto dev = mKeyStore->getDevice(keyBlob);
if (!dev) {
- *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
}
// If the charBlob is up to date, it simply moves the argument blobs to the returned blobs
// and extracts the characteristics on the way. Otherwise it updates the cache file with data
// from keymaster. It may also upgrade the key blob.
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
-
dev->getKeyCharacteristics(
std::move(lockedEntry), clientId.getData(), appData.getData(), std::move(keyBlob),
std::move(charBlob),
- [&](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
- if (outCharacteristics && rc.isOk()) {
- *outCharacteristics = std::move(keyCharacteristics);
- }
- resultPromise.set_value(rc);
+ [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+ cb->onFinished(rc,
+ android::security::keymaster::KeyCharacteristics(keyCharacteristics));
});
- resultFuture.wait();
- *aidl_return = int32_t(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status
-KeyStoreService::importKey(const String16& name, const KeymasterArguments& params, int32_t format,
- const ::std::vector<uint8_t>& keyData, int uid, int flags,
- ::android::security::keymaster::KeyCharacteristics* outCharacteristics,
- int32_t* aidl_return) {
+Status KeyStoreService::importKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+ const String16& name, const KeymasterArguments& params, int32_t format,
+ const ::std::vector<uint8_t>& keyData, int uid, int flags, int32_t* _aidl_return) {
uid = getEffectiveUid(uid);
auto logOnScopeExit = android::base::make_scope_guard([&] {
if (__android_log_security()) {
android_log_event_list(SEC_TAG_KEY_IMPORTED)
- << int32_t(*aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
+ << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
<< String8(name) << int32_t(uid) << LOG_ID_SECURITY;
}
});
@@ -713,21 +687,18 @@ KeyStoreService::importKey(const String16& name, const KeymasterArguments& param
checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!rc.isOk()) {
LOG(ERROR) << "permissission denied";
- *aidl_return = static_cast<int32_t>(rc);
- return Status::ok();
+ return AIDL_RETURN(rc);
}
if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
- *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
SecurityLevel securityLevel = flagsToSecurityLevel(flags);
auto dev = mKeyStore->getDevice(securityLevel);
if (!dev) {
LOG(ERROR) << "importKey - cound not get keymaster device";
- *aidl_return = static_cast<int32_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
}
String8 name8(name);
@@ -735,44 +706,37 @@ KeyStoreService::importKey(const String16& name, const KeymasterArguments& param
if (!lockedEntry) {
LOG(ERROR) << "importKey - key: " << name8.string() << " " << int(uid)
<< " already exists.";
- *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
}
logOnScopeExit.Disable();
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
+ dev->importKey(
+ std::move(lockedEntry), params.getParameters(), KeyFormat(format), keyData, flags,
+ [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+ if (__android_log_security()) {
+ android_log_event_list(SEC_TAG_KEY_IMPORTED)
+ << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
+ }
+ cb->onFinished(rc,
+ android::security::keymaster::KeyCharacteristics(keyCharacteristics));
+ });
- dev->importKey(std::move(lockedEntry), params.getParameters(), KeyFormat(format), keyData,
- flags,
- [&, uid](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
- if (outCharacteristics && rc.isOk()) {
- *outCharacteristics = std::move(keyCharacteristics);
- }
- if (__android_log_security()) {
- android_log_event_list(SEC_TAG_KEY_IMPORTED)
- << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
- }
- resultPromise.set_value(rc);
- });
-
- resultFuture.wait();
- *aidl_return = int32_t(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status KeyStoreService::exportKey(const String16& name, int32_t format,
- const ::android::security::keymaster::KeymasterBlob& clientId,
- const ::android::security::keymaster::KeymasterBlob& appData,
- int32_t uid, ExportResult* result) {
+Status KeyStoreService::exportKey(
+ const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
+ const String16& name, int32_t format,
+ const ::android::security::keymaster::KeymasterBlob& clientId,
+ const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
+ int32_t* _aidl_return) {
uid_t targetUid = getEffectiveUid(uid);
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!is_granted_to(callingUid, targetUid)) {
ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
- result->resultCode = ResponseCode::PERMISSION_DENIED;
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
String8 name8(name);
@@ -785,43 +749,35 @@ Status KeyStoreService::exportKey(const String16& name, int32_t format,
std::tie(rc, keyBlob, charBlob, lockedEntry) =
mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
if (!rc) {
- result->resultCode = rc;
- return Status::ok();
+ return AIDL_RETURN(rc);
}
auto dev = mKeyStore->getDevice(keyBlob);
- std::promise<void> resultPromise;
- auto resultFuture = resultPromise.get_future();
dev->exportKey(std::move(lockedEntry), KeyFormat(format), clientId.getData(), appData.getData(),
- std::move(keyBlob), std::move(charBlob), [&](ExportResult exportResult) {
- *result = std::move(exportResult);
- resultPromise.set_value();
- });
+ std::move(keyBlob), std::move(charBlob),
+ [cb](ExportResult exportResult) { cb->onFinished(exportResult); });
- resultFuture.wait();
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, int32_t purpose,
+Status KeyStoreService::begin(const sp<IKeystoreOperationResultCallback>& cb,
+ const sp<IBinder>& appToken, const String16& name, int32_t purpose,
bool pruneable, const KeymasterArguments& params,
const ::std::vector<uint8_t>& entropy, int32_t uid,
- OperationResult* result) {
+ int32_t* _aidl_return) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
uid_t targetUid = getEffectiveUid(uid);
if (!is_granted_to(callingUid, targetUid)) {
ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
- result->resultCode = ResponseCode::PERMISSION_DENIED;
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
- result->resultCode = ResponseCode::PERMISSION_DENIED;
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
}
if (!checkAllowedOperationParams(params.getParameters())) {
- result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
String8 name8(name);
@@ -834,104 +790,85 @@ Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name,
mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
if (rc == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
- return result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED, Status::ok();
+ return AIDL_RETURN(ErrorCode::KEY_USER_NOT_AUTHENTICATED);
}
- if (rc != ResponseCode::NO_ERROR) return result->resultCode = rc, Status::ok();
+ if (rc != ResponseCode::NO_ERROR) return AIDL_RETURN(rc);
auto dev = mKeyStore->getDevice(keyBlob);
AuthorizationSet opParams = params.getParameters();
- KeyCharacteristics characteristics;
-
- std::promise<void> resultPromise;
- auto resultFuture = resultPromise.get_future();
dev->begin(std::move(lockedEntry), appToken, std::move(keyBlob), std::move(charBlob), pruneable,
static_cast<KeyPurpose>(purpose), std::move(opParams), entropy,
- [&, this](OperationResult result_) {
+ [this, cb, dev](OperationResult result_) {
if (result_.resultCode.isOk() ||
result_.resultCode == ResponseCode::OP_AUTH_NEEDED) {
addOperationDevice(result_.token, dev);
}
- if (result) *result = std::move(result_);
- resultPromise.set_value();
+ cb->onFinished(result_);
});
- resultFuture.wait();
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status KeyStoreService::update(const sp<IBinder>& token, const KeymasterArguments& params,
- const ::std::vector<uint8_t>& data, OperationResult* result) {
+Status KeyStoreService::update(const ::android::sp<IKeystoreOperationResultCallback>& cb,
+ const ::android::sp<::android::IBinder>& token,
+ const ::android::security::keymaster::KeymasterArguments& params,
+ const ::std::vector<uint8_t>& input, int32_t* _aidl_return) {
if (!checkAllowedOperationParams(params.getParameters())) {
- result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
- std::promise<void> resultPromise;
- auto resultFuture = resultPromise.get_future();
-
auto dev = getOperationDevice(token);
if (!dev) {
- *result = operationFailed(ErrorCode::INVALID_OPERATION_HANDLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
}
- dev->update(token, params.getParameters(), data, [&](OperationResult result_) {
+ dev->update(token, params.getParameters(), input, [this, cb, token](OperationResult result_) {
if (!result_.resultCode.isOk()) {
removeOperationDevice(token);
}
- if (result) *result = std::move(result_);
- resultPromise.set_value();
+ cb->onFinished(result_);
});
- resultFuture.wait();
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArguments& params,
+Status KeyStoreService::finish(const ::android::sp<IKeystoreOperationResultCallback>& cb,
+ const ::android::sp<::android::IBinder>& token,
+ const ::android::security::keymaster::KeymasterArguments& params,
const ::std::vector<uint8_t>& signature,
- const ::std::vector<uint8_t>& entropy, OperationResult* result) {
+ const ::std::vector<uint8_t>& entropy, int32_t* _aidl_return) {
if (!checkAllowedOperationParams(params.getParameters())) {
- result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
- std::promise<void> resultPromise;
- auto resultFuture = resultPromise.get_future();
-
auto dev = getOperationDevice(token);
if (!dev) {
- *result = operationFailed(ErrorCode::INVALID_OPERATION_HANDLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
}
dev->finish(token, params.getParameters(), {}, signature, entropy,
- [&](OperationResult result_) {
+ [this, cb, token](OperationResult result_) {
if (!result_.resultCode.isOk()) {
removeOperationDevice(token);
}
- if (result) *result = std::move(result_);
- resultPromise.set_value();
+ cb->onFinished(result_);
});
- resultFuture.wait();
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status KeyStoreService::abort(const sp<IBinder>& token, int32_t* aidl_return) {
+Status KeyStoreService::abort(const ::android::sp<IKeystoreResponseCallback>& cb,
+ const ::android::sp<::android::IBinder>& token,
+ int32_t* _aidl_return) {
auto dev = getOperationDevice(token);
if (!dev) {
- *aidl_return = static_cast<int32_t>(ErrorCode::INVALID_OPERATION_HANDLE);
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
}
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
- dev->abort(token, [&](KeyStoreServiceReturnCode rc) { resultPromise.set_value(rc); });
+ dev->abort(token, [cb](KeyStoreServiceReturnCode rc) { cb->onFinished(rc); });
- resultFuture.wait();
- *aidl_return = int32_t(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
@@ -987,13 +924,12 @@ int isDeviceIdAttestationRequested(const KeymasterArguments& params) {
return result;
}
-Status KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
- ::android::security::keymaster::KeymasterCertificateChain* chain,
- int32_t* aidl_return) {
+Status KeyStoreService::attestKey(
+ const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+ const String16& name, const KeymasterArguments& params, int32_t* _aidl_return) {
// check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
if (!checkAllowedOperationParams(params.getParameters())) {
- *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1007,15 +943,13 @@ Status KeyStoreService::attestKey(const String16& name, const KeymasterArguments
// unique device ID.
if ((needsIdAttestation && !isSomeUserSystemUid) ||
(needsUniqueIdAttestation && !isPrimaryUserSystemUid)) {
- *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
- return Status::ok();
+ return AIDL_RETURN(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
}
AuthorizationSet mutableParams = params.getParameters();
KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
if (!rc.isOk()) {
- *aidl_return = static_cast<int32_t>(rc);
- return Status::ok();
+ return AIDL_RETURN(rc);
}
String8 name8(name);
@@ -1026,75 +960,67 @@ Status KeyStoreService::attestKey(const String16& name, const KeymasterArguments
std::tie(rc, keyBlob, charBlob, lockedEntry) =
mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
-
- auto worker_cb = [&](Return<void> rc,
- std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
- auto& [ret, certChain] = hidlResult;
- if (!rc.isOk()) {
- resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
- return;
- }
- if (ret == ErrorCode::OK && chain) {
- *chain = KeymasterCertificateChain(certChain);
- }
- resultPromise.set_value(ret);
- };
auto dev = mKeyStore->getDevice(keyBlob);
auto hidlKey = blob2hidlVec(keyBlob);
- dev->attestKey(std::move(hidlKey), mutableParams.hidl_data(), worker_cb);
+ dev->attestKey(
+ std::move(hidlKey), mutableParams.hidl_data(),
+ [cb](Return<void> rc, std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
+ auto& [ret, certChain] = hidlResult;
+ if (!rc.isOk()) {
+ cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
+ } else if (ret != ErrorCode::OK) {
+ cb->onFinished(KeyStoreServiceReturnCode(ret), {});
+ } else {
+ cb->onFinished(KeyStoreServiceReturnCode(ret),
+ KeymasterCertificateChain(std::move(certChain)));
+ }
+ });
- resultFuture.wait();
- *aidl_return = static_cast<int32_t>(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
-Status
-KeyStoreService::attestDeviceIds(const KeymasterArguments& params,
- ::android::security::keymaster::KeymasterCertificateChain* chain,
- int32_t* aidl_return) {
+// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
+// It should never be redefined by a build system though.
+#ifndef CAPTURE_MOVE
+#define CAPTURE_MOVE(x) x = std::move(x)
+#endif
+
+Status KeyStoreService::attestDeviceIds(
+ const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+ const KeymasterArguments& params, int32_t* _aidl_return) {
// check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
if (!checkAllowedOperationParams(params.getParameters())) {
- *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
if (!isDeviceIdAttestationRequested(params)) {
// There is an attestKey() method for attesting keys without device ID attestation.
- *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
if (binder == nullptr) {
- *aidl_return =
- static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
}
if (!interface_cast<IPermissionController>(binder)->checkPermission(
String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
IPCThreadState::self()->getCallingPid(), callingUid)) {
- *aidl_return =
- static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
- return Status::ok();
+ return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
}
AuthorizationSet mutableParams = params.getParameters();
KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
if (!rc.isOk()) {
- *aidl_return = static_cast<int32_t>(rc);
- return Status::ok();
+ return AIDL_RETURN(rc);
}
// Generate temporary key.
auto dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
if (!dev) {
- *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
}
@@ -1110,44 +1036,45 @@ KeyStoreService::attestDeviceIds(const KeymasterArguments& params,
dev->generateKey(
keyCharacteristics.hidl_data(),
- [&, dev](Return<void> rc,
- std::tuple<ErrorCode, ::std::vector<uint8_t>, KeyCharacteristics>&& hidlResult) {
+ [cb, dev, CAPTURE_MOVE(mutableParams)](
+ Return<void> rc,
+ std::tuple<ErrorCode, ::std::vector<uint8_t>, KeyCharacteristics>&& hidlResult) {
auto& [ret, hidlKeyBlob_, dummyCharacteristics] = hidlResult;
auto hidlKeyBlob = std::move(hidlKeyBlob_);
if (!rc.isOk()) {
- resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
+ cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
return;
}
if (ret != ErrorCode::OK) {
- resultPromise.set_value(ret);
+ cb->onFinished(KeyStoreServiceReturnCode(ret), {});
return;
}
dev->attestKey(
hidlKeyBlob, mutableParams.hidl_data(),
- [&, dev,
+ [cb, dev,
hidlKeyBlob](Return<void> rc,
std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
auto& [ret, certChain] = hidlResult;
- // shedule temp key for deletion
+ // schedule temp key for deletion
dev->deleteKey(std::move(hidlKeyBlob), [](Return<ErrorCode> rc) {
// log error but don't return an error
KS_HANDLE_HIDL_ERROR(rc);
});
if (!rc.isOk()) {
- resultPromise.set_value(ResponseCode::SYSTEM_ERROR);
+ cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
return;
}
- if (ret == ErrorCode::OK && chain) {
- *chain =
- ::android::security::keymaster::KeymasterCertificateChain(certChain);
+ if (ret == ErrorCode::OK) {
+ cb->onFinished(
+ KeyStoreServiceReturnCode(ret),
+ ::android::security::keymaster::KeymasterCertificateChain(certChain));
+ } else {
+ cb->onFinished(KeyStoreServiceReturnCode(ret), {});
}
- resultPromise.set_value(ret);
});
});
- resultFuture.wait();
- *aidl_return = static_cast<int32_t>(resultFuture.get());
- return Status::ok();
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
@@ -1157,14 +1084,12 @@ Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
return Status::ok();
}
-#define AIDL_RETURN(rc) \
- (*_aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(rc)), Status::ok())
-
Status KeyStoreService::importWrappedKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
const KeymasterArguments& params, int64_t rootSid, int64_t fingerprintSid,
- ::android::security::keymaster::KeyCharacteristics* outCharacteristics, int32_t* _aidl_return) {
+ int32_t* _aidl_return) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1198,22 +1123,15 @@ Status KeyStoreService::importWrappedKey(
return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
}
- std::promise<KeyStoreServiceReturnCode> resultPromise;
- auto resultFuture = resultPromise.get_future();
-
dev->importWrappedKey(
std::move(wrappingLockedEntry), std::move(wrappedLockedEntry), wrappedKey, maskingKey,
params.getParameters(), std::move(wrappingKeyBlob), std::move(wrappingCharBlob), rootSid,
- fingerprintSid, [&](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
- if (rc.isOk() && outCharacteristics) {
- *outCharacteristics =
- ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
- }
- resultPromise.set_value(rc);
+ fingerprintSid, [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
+ cb->onFinished(rc,
+ ::android::security::keymaster::KeyCharacteristics(keyCharacteristics));
});
- resultFuture.wait();
- return AIDL_RETURN(resultFuture.get());
+ return AIDL_RETURN(ResponseCode::NO_ERROR);
}
Status KeyStoreService::presentConfirmationPrompt(const sp<IBinder>& listener,
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 29369d05..601ed211 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -17,7 +17,7 @@
#ifndef KEYSTORE_KEYSTORE_SERVICE_H_
#define KEYSTORE_KEYSTORE_SERVICE_H_
-#include <android/security/BnKeystoreService.h>
+#include <android/security/keystore/BnKeystoreService.h>
#include "auth_token_table.h"
#include "confirmation_manager.h"
@@ -42,7 +42,7 @@ namespace keystore {
// java/android/security/IKeystoreService.aidl Note that all generated methods return binder::Status
// and use last arguments to send actual result to the caller. Private methods don't need to handle
// binder::Status. Input parameters cannot be null unless annotated with @nullable in .aidl file.
-class KeyStoreService : public android::security::BnKeystoreService {
+class KeyStoreService : public android::security::keystore::BnKeystoreService {
public:
explicit KeyStoreService(sp<KeyStore> keyStore) : mKeyStore(keyStore) {}
virtual ~KeyStoreService() = default;
@@ -78,71 +78,76 @@ class KeyStoreService : public android::security::BnKeystoreService {
::android::binder::Status is_hardware_backed(const ::android::String16& string,
int32_t* _aidl_return) override;
::android::binder::Status clear_uid(int64_t uid, int32_t* _aidl_return) override;
- ::android::binder::Status addRngEntropy(const ::std::vector<uint8_t>& data, int32_t flags,
- int32_t* _aidl_return) override;
::android::binder::Status
- generateKey(const ::android::String16& alias,
- const ::android::security::keymaster::KeymasterArguments& arguments,
- const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
- ::android::security::keymaster::KeyCharacteristics* characteristics,
- int32_t* _aidl_return) override;
- ::android::binder::Status
- getKeyCharacteristics(const ::android::String16& alias,
- const ::android::security::keymaster::KeymasterBlob& clientId,
- const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
- ::android::security::keymaster::KeyCharacteristics* characteristics,
- int32_t* _aidl_return) override;
- ::android::binder::Status
- importKey(const ::android::String16& alias,
- const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
- const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
- ::android::security::keymaster::KeyCharacteristics* characteristics,
- int32_t* _aidl_return) override;
+ addRngEntropy(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+ const ::std::vector<uint8_t>& data, int32_t flags,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status generateKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+ const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterArguments& arguments,
+ const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status getKeyCharacteristics(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+ const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterBlob& clientId,
+ const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status importKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
+ const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
+ const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
+ int32_t* _aidl_return) override;
::android::binder::Status
- exportKey(const ::android::String16& alias, int32_t format,
+ exportKey(const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
+ const ::android::String16& alias, int32_t format,
const ::android::security::keymaster::KeymasterBlob& clientId,
const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
- ::android::security::keymaster::ExportResult* _aidl_return) override;
+ int32_t* _aidl_return) override;
::android::binder::Status
- begin(const ::android::sp<::android::IBinder>& appToken, const ::android::String16& alias,
+ begin(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+ const ::android::sp<::android::IBinder>& appToken, const ::android::String16& alias,
int32_t purpose, bool pruneable,
const ::android::security::keymaster::KeymasterArguments& params,
- const ::std::vector<uint8_t>& entropy, int32_t uid,
- ::android::security::keymaster::OperationResult* _aidl_return) override;
+ const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t* _aidl_return) override;
::android::binder::Status
- update(const ::android::sp<::android::IBinder>& token,
+ update(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+ const ::android::sp<::android::IBinder>& token,
const ::android::security::keymaster::KeymasterArguments& params,
- const ::std::vector<uint8_t>& input,
- ::android::security::keymaster::OperationResult* _aidl_return) override;
+ const ::std::vector<uint8_t>& input, int32_t* _aidl_return) override;
::android::binder::Status
- finish(const ::android::sp<::android::IBinder>& token,
+ finish(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
+ const ::android::sp<::android::IBinder>& token,
const ::android::security::keymaster::KeymasterArguments& params,
const ::std::vector<uint8_t>& signature, const ::std::vector<uint8_t>& entropy,
- ::android::security::keymaster::OperationResult* _aidl_return) override;
- ::android::binder::Status abort(const ::android::sp<::android::IBinder>& handle,
- int32_t* _aidl_return) override;
+ int32_t* _aidl_return) override;
+ ::android::binder::Status
+ abort(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
+ const ::android::sp<::android::IBinder>& token, int32_t* _aidl_return) override;
::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
int32_t* _aidl_return) override;
::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
int32_t* _aidl_return) override;
::android::binder::Status onUserRemoved(int32_t userId, int32_t* _aidl_return) override;
- ::android::binder::Status
- attestKey(const ::android::String16& alias,
- const ::android::security::keymaster::KeymasterArguments& params,
- ::android::security::keymaster::KeymasterCertificateChain* chain,
- int32_t* _aidl_return) override;
- ::android::binder::Status
- attestDeviceIds(const ::android::security::keymaster::KeymasterArguments& params,
- ::android::security::keymaster::KeymasterCertificateChain* chain,
- int32_t* _aidl_return) override;
+ ::android::binder::Status attestKey(
+ const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+ const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterArguments& params,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status attestDeviceIds(
+ const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
+ const ::android::security::keymaster::KeymasterArguments& params,
+ int32_t* _aidl_return) override;
::android::binder::Status onDeviceOffBody(int32_t* _aidl_return) override;
::android::binder::Status importWrappedKey(
+ const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
const ::android::security::keymaster::KeymasterArguments& params, int64_t rootSid,
- int64_t fingerprintSid, ::android::security::keymaster::KeyCharacteristics* characteristics,
- int32_t* _aidl_return) override;
+ int64_t fingerprintSid, int32_t* _aidl_return) override;
::android::binder::Status presentConfirmationPrompt(
const ::android::sp<::android::IBinder>& listener, const ::android::String16& promptText,
diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp
index 1002b8d5..f3bf71fd 100644
--- a/keystore/keymaster_worker.cpp
+++ b/keystore/keymaster_worker.cpp
@@ -37,34 +37,31 @@ using android::security::keymaster::ExportResult;
using android::security::keymaster::operationFailed;
using android::security::keymaster::OperationResult;
-Worker::Worker() {
- worker_ = std::thread([this] {
- std::unique_lock<std::mutex> lock(pending_requests_mutex_);
- running_ = true;
- while (running_) {
- pending_requests_cond_var_.wait(
- lock, [this]() { return !pending_requests_.empty() || !running_; });
- if (!running_) break;
- auto request = std::move(pending_requests_.front());
- pending_requests_.pop();
- lock.unlock();
- request();
- lock.lock();
- }
- });
-}
+Worker::Worker() {}
Worker::~Worker() {
- if (worker_.joinable()) {
- running_ = false;
- pending_requests_cond_var_.notify_all();
- worker_.join();
- }
+ std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+ pending_requests_cond_var_.wait(lock, [this] { return pending_requests_.empty(); });
}
void Worker::addRequest(WorkerTask request) {
std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+ bool start_thread = pending_requests_.empty();
pending_requests_.push(std::move(request));
lock.unlock();
- pending_requests_cond_var_.notify_all();
+ if (start_thread) {
+ auto worker = std::thread([this] {
+ std::unique_lock<std::mutex> lock(pending_requests_mutex_);
+ running_ = true;
+ while (!pending_requests_.empty()) {
+ auto request = std::move(pending_requests_.front());
+ lock.unlock();
+ request();
+ lock.lock();
+ pending_requests_.pop();
+ pending_requests_cond_var_.notify_all();
+ }
+ });
+ worker.detach();
+ }
}
KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h
index b39ae83a..2a35977a 100644
--- a/keystore/keymaster_worker.h
+++ b/keystore/keymaster_worker.h
@@ -113,7 +113,6 @@ class Worker {
std::queue<WorkerTask> pending_requests_;
std::mutex pending_requests_mutex_;
std::condition_variable pending_requests_cond_var_;
- std::thread worker_;
bool running_ = false;
public:
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
index db9b9838..cdeaf321 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
@@ -21,14 +21,13 @@
#include <keystore/KeyCharacteristics.h>
#include <keystore/KeymasterBlob.h>
#include <keystore/KeymasterCertificateChain.h>
-#include <keystore/KeystoreArg.h>
#include <keystore/keymaster_types.h>
#include <keystore/keystore_hidl_support.h>
namespace keystore {
// reads byte[]
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in) {
ssize_t length = in.readInt32();
if (length <= 0) {
@@ -38,7 +37,7 @@ hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
const void* buf = in.readInplace(length);
if (!buf) return {};
- return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
+ return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length));
}
android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
@@ -235,7 +234,7 @@ status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
}
status_t KeymasterBlob::readFromParcel(const Parcel* in) {
- data_ = keystore::readKeymasterBlob(*in, true /* in place */);
+ data_ = keystore::readKeymasterBlob(*in);
return OK;
}
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
index 13edbd25..ea72197a 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.h
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.h
@@ -60,7 +60,7 @@ inline android::status_t nullable(android::Parcel* out) {
/**
* makes a copy only if inPlace is false
*/
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace = true);
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in);
android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out);
NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace = true);
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index b58735e2..2705a194 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -20,7 +20,7 @@
#include <sys/types.h>
#include <vector>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -28,7 +28,7 @@
using namespace android;
using namespace keystore;
-using android::security::IKeystoreService;
+using android::security::keystore::IKeystoreService;
static const char* responses[] = {
nullptr,
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 157417f8..0981f1eb 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -29,7 +29,7 @@
#include <android/hardware/confirmationui/1.0/types.h>
#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -41,7 +41,7 @@ using keystore::KeystoreClient;
using android::sp;
using android::String16;
-using android::security::IKeystoreService;
+using android::security::keystore::IKeystoreService;
using base::CommandLine;
using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index 6d998ada..18e9eb11 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -16,10 +16,11 @@
#include "keystore/keystore_client_impl.h"
+#include <future>
#include <string>
#include <vector>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/IServiceManager.h>
@@ -30,6 +31,7 @@
#include <keystore/keymaster_types.h>
#include <keystore/keystore_hidl_support.h>
+#include <keystore/keystore_promises.h>
#include "keystore_client.pb.h"
@@ -46,6 +48,7 @@ constexpr uint32_t kHMACOutputSize = 256; // bits
using android::String16;
using android::security::keymaster::ExportResult;
using android::security::keymaster::OperationResult;
+using android::security::keystore::KeystoreResponse;
using keystore::AuthorizationSet;
using keystore::AuthorizationSetBuilder;
using keystore::KeyCharacteristics;
@@ -57,7 +60,8 @@ namespace keystore {
KeystoreClientImpl::KeystoreClientImpl() {
service_manager_ = android::defaultServiceManager();
keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
- keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
+ keystore_ =
+ android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
}
bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
@@ -180,10 +184,21 @@ bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string&
KeyStoreNativeReturnCode
KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
- int32_t result;
- auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), flags, &result);
+ int32_t error_code;
+
+ android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise());
+ auto future = promise->get_future();
+
+ auto binder_result =
+ keystore_->addRngEntropy(promise, blob2hidlVec(entropy), flags, &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
- return KeyStoreNativeReturnCode(result);
+
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ auto result = future.get();
+
+ return KeyStoreNativeReturnCode(result.response_code());
}
KeyStoreNativeReturnCode
@@ -191,19 +206,26 @@ KeystoreClientImpl::generateKey(const std::string& key_name, const Authorization
int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
- ::android::security::keymaster::KeyCharacteristics characteristics;
- int32_t result;
+ int32_t error_code;
+ android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+ auto future = promise->get_future();
auto binder_result = keystore_->generateKey(
- key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
- hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &characteristics, &result);
+ promise, key_name16,
+ ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
+ hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ auto [km_response, characteristics] = future.get();
+
/* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
* There are no references to Parcel memory after that, and ownership of the newly acquired
* memory is with the AuthorizationSet objects. */
*hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
*software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
- return KeyStoreNativeReturnCode(result);
+ return KeyStoreNativeReturnCode(km_response.response_code());
}
KeyStoreNativeReturnCode
@@ -211,18 +233,25 @@ KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
AuthorizationSet* hardware_enforced_characteristics,
AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
- ::android::security::keymaster::KeyCharacteristics characteristics;
- int32_t result;
+ int32_t error_code;
+ android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+ auto future = promise->get_future();
auto binder_result = keystore_->getKeyCharacteristics(
- key_name16, android::security::keymaster::KeymasterBlob(),
- android::security::keymaster::KeymasterBlob(), kDefaultUID, &characteristics, &result);
+ promise, key_name16, android::security::keymaster::KeymasterBlob(),
+ android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ auto [km_response, characteristics] = future.get();
/* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
* There are no references to Parcel memory after that, and ownership of the newly acquired
* memory is with the AuthorizationSet objects. */
*hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
*software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
- return KeyStoreNativeReturnCode(result);
+ return KeyStoreNativeReturnCode(km_response.response_code());
}
KeyStoreNativeReturnCode
@@ -232,29 +261,48 @@ KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSe
AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
auto hidlKeyData = blob2hidlVec(key_data);
- ::android::security::keymaster::KeyCharacteristics characteristics;
- int32_t result;
+ int32_t error_code;
+ android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
+ auto future = promise->get_future();
auto binder_result = keystore_->importKey(
- key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
- (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics, &result);
+ promise, key_name16,
+ ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
+ (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &error_code);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ auto [km_response, characteristics] = future.get();
+
/* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
* There are no references to Parcel memory after that, and ownership of the newly acquired
* memory is with the AuthorizationSet objects. */
*hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
*software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
- return KeyStoreNativeReturnCode(result);
+ return KeyStoreNativeReturnCode(km_response.response_code());
}
KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
const std::string& key_name,
std::string* export_data) {
String16 key_name16(key_name.data(), key_name.size());
- ExportResult export_result;
+ int32_t error_code;
+ android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
+ auto future = promise->get_future();
auto binder_result = keystore_->exportKey(
- key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
- android::security::keymaster::KeymasterBlob(), kDefaultUID, &export_result);
+ promise, key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
+ android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ auto export_result = future.get();
+ if (!export_result.resultCode.isOk()) return export_result.resultCode;
+
*export_data = hidlVec2String(export_result.exportData);
+
return export_result.resultCode;
}
@@ -279,12 +327,18 @@ KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_na
AuthorizationSet* output_parameters, uint64_t* handle) {
android::sp<android::IBinder> token(new android::BBinder);
String16 key_name16(key_name.data(), key_name.size());
- OperationResult result;
+ int32_t error_code;
+ android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+ auto future = promise->get_future();
auto binder_result = keystore_->begin(
- token, key_name16, (int)purpose, true /*pruneable*/,
+ promise, token, key_name16, (int)purpose, true /*pruneable*/,
android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
- hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &result);
+ hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ OperationResult result = future.get();
if (result.resultCode.isOk()) {
*handle = getNextVirtualHandle();
active_operations_[*handle] = result.token;
@@ -302,13 +356,19 @@ KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& inp
if (active_operations_.count(handle) == 0) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
- OperationResult result;
auto hidlInputData = blob2hidlVec(input_data);
+ int32_t error_code;
+ android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+ auto future = promise->get_future();
auto binder_result = keystore_->update(
- active_operations_[handle],
+ promise, active_operations_[handle],
android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
- hidlInputData, &result);
+ hidlInputData, &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+
+ OperationResult result = future.get();
if (result.resultCode.isOk()) {
*num_input_bytes_consumed = result.inputConsumed;
@@ -328,14 +388,19 @@ KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& inp
if (active_operations_.count(handle) == 0) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
- OperationResult result;
+ int32_t error_code;
auto hidlSignature = blob2hidlVec(signature_to_verify);
+ android::sp<OperationResultPromise> promise(new OperationResultPromise{});
+ auto future = promise->get_future();
auto binder_result = keystore_->finish(
- active_operations_[handle],
+ promise, active_operations_[handle],
android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
- (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &result);
+ (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &error_code);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ KeyStoreNativeReturnCode rc(error_code);
+ if (!rc.isOk()) return rc;
+ OperationResult result = future.get();
if (result.resultCode.isOk()) {
if (result.outParams.size()) {
*output_parameters = result.outParams;
@@ -352,13 +417,18 @@ KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
int32_t result;
+ android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise{});
+ auto future = promise->get_future();
// Current implementation does not return exceptions in android::binder::Status
- auto binder_result = keystore_->abort(active_operations_[handle], &result);
+ auto binder_result = keystore_->abort(promise, active_operations_[handle], &result);
if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
- if (KeyStoreNativeReturnCode(result).isOk()) {
+ KeyStoreNativeReturnCode rc(result);
+ if (!rc.isOk()) return rc;
+ rc = KeyStoreNativeReturnCode(future.get().response_code());
+ if (rc.isOk()) {
active_operations_.erase(handle);
}
- return KeyStoreNativeReturnCode(result);
+ return rc;
}
bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
index fec36c4c..a6f87557 100644
--- a/keystore/keystore_get.cpp
+++ b/keystore/keystore_get.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IServiceManager.h>
#include <keystore/keystore_get.h>
@@ -26,8 +26,8 @@ using namespace keystore;
ssize_t keystore_get(const char* key, size_t keyLength, uint8_t** value) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
- sp<android::security::IKeystoreService> service =
- interface_cast<android::security::IKeystoreService>(binder);
+ sp<android::security::keystore::IKeystoreService> service =
+ interface_cast<android::security::keystore::IKeystoreService>(binder);
if (service == nullptr) {
return -1;
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index c05d1428..409ac837 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -18,7 +18,7 @@
#include <android-base/logging.h>
#include <android/hidl/manager/1.1/IServiceManager.h>
-#include <android/security/IKeystoreService.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <android/system/wifi/keystore/1.0/IKeystore.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 71e8ed2e..78056d64 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -107,8 +107,7 @@ void log_key_integrity_violation(const char* name, uid_t uid) {
namespace keystore {
hidl_vec<uint8_t> blob2hidlVec(const Blob& blob) {
- hidl_vec<uint8_t> result;
- result.setToExternal(const_cast<uint8_t*>(blob.getValue()), blob.getLength());
+ hidl_vec<uint8_t> result(blob.getValue(), blob.getValue() + blob.getLength());
return result;
}
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
index 1f1aa968..4073b42e 100644
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -132,14 +132,18 @@ inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& bl
}
inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
- hidl_vec<uint8_t> result;
- result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
- return result;
+ if (blob.key_material == nullptr || blob.key_material_size == 0) {
+ return {};
+ } else {
+ return hidl_vec<uint8_t>(blob.key_material, blob.key_material + blob.key_material_size);
+ }
}
inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
- hidl_vec<uint8_t> result;
- result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
- return result;
+ if (blob.data == nullptr || blob.data_length == 0) {
+ return {};
+ } else {
+ return hidl_vec<uint8_t>(blob.data, blob.data + blob.data_length);
+ }
}
inline static hidl_vec<hidl_vec<uint8_t>>
@@ -186,8 +190,7 @@ static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_s
break;
case KM_BIGNUM:
case KM_BYTES:
- result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
- params[i].blob.data_length);
+ result[i].blob = kmBlob2hidlVec(params[i].blob);
break;
case KM_INVALID:
default: