Merge changes from topic "async_keystore2"

* changes:
  Start keymaster workers on demand
  Multi-threaded keystore
This commit is contained in:
Janis Danisevskis 2018-11-15 01:19:10 +00:00 committed by Gerrit Code Review
commit adde739791
35 changed files with 832 additions and 594 deletions

View file

@ -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 \

View file

@ -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);

View file

@ -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;
}

View file

@ -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",
}

View file

@ -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>

View file

@ -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

View 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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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";

View file

@ -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);
}

View file

@ -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

View file

@ -16,6 +16,7 @@
#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
#include <binder/Parcelable.h>
#include <keystore/keymaster_types.h>
namespace android {
namespace security {

View file

@ -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

View file

@ -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_

View 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_

View file

@ -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_;

View 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_

View file

@ -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,

View file

@ -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,

View file

@ -37,34 +37,31 @@ using android::security::keymaster::ExportResult;
using android::security::keymaster::operationFailed;
using android::security::keymaster::OperationResult;
Worker::Worker() {
worker_ = std::thread([this] {
std::unique_lock<std::mutex> lock(pending_requests_mutex_);
running_ = true;
while (running_) {
pending_requests_cond_var_.wait(
lock, [this]() { return !pending_requests_.empty() || !running_; });
if (!running_) break;
auto request = std::move(pending_requests_.front());
pending_requests_.pop();
lock.unlock();
request();
lock.lock();
}
});
}
Worker::Worker() {}
Worker::~Worker() {
if (worker_.joinable()) {
running_ = false;
pending_requests_cond_var_.notify_all();
worker_.join();
}
std::unique_lock<std::mutex> lock(pending_requests_mutex_);
pending_requests_cond_var_.wait(lock, [this] { return pending_requests_.empty(); });
}
void Worker::addRequest(WorkerTask request) {
std::unique_lock<std::mutex> lock(pending_requests_mutex_);
bool start_thread = pending_requests_.empty();
pending_requests_.push(std::move(request));
lock.unlock();
pending_requests_cond_var_.notify_all();
if (start_thread) {
auto worker = std::thread([this] {
std::unique_lock<std::mutex> lock(pending_requests_mutex_);
running_ = true;
while (!pending_requests_.empty()) {
auto request = std::move(pending_requests_.front());
lock.unlock();
request();
lock.lock();
pending_requests_.pop();
pending_requests_cond_var_.notify_all();
}
});
worker.detach();
}
}
KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)

View file

@ -113,7 +113,6 @@ class Worker {
std::queue<WorkerTask> pending_requests_;
std::mutex pending_requests_mutex_;
std::condition_variable pending_requests_cond_var_;
std::thread worker_;
bool running_ = false;
public:

View file

@ -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;
}

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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>

View file

@ -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;
}

View file

@ -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: