Multi-threaded keystore
This patches changes the keystore to use the asychronous api model for begin, update, finish, and abort. Also removes unused class KeystoreArguments (aidl and implementation). Test: Keystore CTS tests Bug: 111443219 Change-Id: Icc6def9ff6dbe32193272d7d015079a006ebc430
This commit is contained in:
parent
81c7e390e7
commit
bb6cabdaa1
33 changed files with 813 additions and 571 deletions
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 algorithm = getKeyAlgoritmFromKeyCharacteristics(keyCharacteristics);
|
||||
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(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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
43
keystore/KeystoreResponse.cpp
Normal file
43
keystore/KeystoreResponse.cpp
Normal file
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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";
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
|
||||
|
||||
#include <binder/Parcelable.h>
|
||||
#include <keystore/keymaster_types.h>
|
||||
|
||||
namespace android {
|
||||
namespace security {
|
||||
|
|
|
@ -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
|
|
@ -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_
|
62
keystore/include/keystore/KeystoreResponse.h
Normal file
62
keystore/include/keystore/KeystoreResponse.h
Normal file
|
@ -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_
|
|
@ -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_;
|
||||
|
||||
|
|
72
keystore/include/keystore/keystore_promises.h
Normal file
72
keystore/include/keystore/keystore_promises.h
Normal file
|
@ -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_
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
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
|
||||
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;
|
||||
::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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue