Fixing bug in security vulnerability patch am: 1e6d4bfd3e am: c18ffb3bd3 -s ours am: 31629ba10d -s ours
am: 488e02bff4 -s ours
Change-Id: I0820d5fad6b8cb8ed845ee5ec6cf453a75a26277
diff --git a/keystore-engine/.clang-format b/keystore-engine/.clang-format
new file mode 100644
index 0000000..b0dc94c
--- /dev/null
+++ b/keystore-engine/.clang-format
@@ -0,0 +1,10 @@
+BasedOnStyle: LLVM
+IndentWidth: 4
+UseTab: Never
+BreakBeforeBraces: Attach
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: true
+IndentCaseLabels: false
+ColumnLimit: 100
+PointerBindsToType: true
+SpacesBeforeTrailingComments: 2
diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index 8988857..c995dfc 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -30,6 +30,7 @@
libcrypto \
libcutils \
libhidlbase \
+ libkeystore_aidl \
libkeystore_binder \
liblog \
libutils
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
index dce8242..f9e7be0 100644
--- a/keystore-engine/keystore_backend_binder.cpp
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -22,11 +22,12 @@
#include "keystore_backend_binder.h"
+#include <android/security/IKeystoreService.h>
#include <binder/IServiceManager.h>
#include <keystore/keystore.h>
-#include <keystore/IKeystoreService.h>
#include <keystore/keystore_hidl_support.h>
+using android::security::IKeystoreService;
using namespace android;
using keystore::blob2hidlVec;
using keystore::hidl_vec;
@@ -35,9 +36,8 @@
const char keystore_service_name[] = "android.security.keystore";
};
-int32_t KeystoreBackendBinder::sign(
- const char *key_id, const uint8_t* in, size_t len, uint8_t** reply,
- size_t* reply_len) {
+int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_t len,
+ uint8_t** reply, size_t* reply_len) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16(keystore_service_name));
sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
@@ -47,20 +47,21 @@
return -1;
}
- auto inBlob = blob2hidlVec(in ,len);
- hidl_vec<uint8_t> reply_vec;
+ auto inBlob = blob2hidlVec(in, len);
+ std::vector<uint8_t> reply_vec;
auto ret = service->sign(String16(key_id), inBlob, &reply_vec);
if (!ret.isOk()) {
return -1;
}
- *reply = reply_vec.releaseData();
+ hidl_vec<uint8_t> reply_hidl(reply_vec); // makes copy
+ *reply = reply_hidl.releaseData();
*reply_len = reply_vec.size();
return 0;
}
-int32_t KeystoreBackendBinder::get_pubkey(
- const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
+int32_t KeystoreBackendBinder::get_pubkey(const char* key_id, uint8_t** pubkey,
+ size_t* pubkey_len) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16(keystore_service_name));
sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
@@ -70,13 +71,14 @@
return -1;
}
- hidl_vec<uint8_t> pubkey_vec;
+ std::vector<uint8_t> pubkey_vec;
auto ret = service->get_pubkey(String16(key_id), &pubkey_vec);
if (!ret.isOk()) {
return -1;
}
- *pubkey = pubkey_vec.releaseData();
+ hidl_vec<uint8_t> hidl_pubkey(pubkey_vec); // makes copy
+ *pubkey = hidl_pubkey.releaseData(); // caller should clean up memory.
*pubkey_len = pubkey_vec.size();
return 0;
}
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 7e91c72..b58671c 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -50,10 +50,11 @@
"libkeymaster_messages",
"libkeymaster_portable",
"libkeymaster_staging",
+ "libkeystore_aidl",
"libkeystore_binder",
+ "libkeystore_parcelables",
"liblog",
"libselinux",
- "libsoftkeymaster",
"libsoftkeymasterdevice",
"libutils",
"libwifikeystorehal",
@@ -68,6 +69,8 @@
enabled: false,
},
},
+
+ required: ["keystore_cli_v2"],
}
cc_binary {
@@ -83,7 +86,9 @@
"libcutils",
"libhidlbase",
"libhwbinder",
+ "libkeystore_aidl", // for IKeyStoreService.asInterface()
"libkeystore_binder",
+ "libkeystore_parcelables",
"liblog",
"libutils",
],
@@ -110,19 +115,44 @@
local_include_dirs: ["include"],
}
+cc_library_shared {
+ name: "libkeystore_parcelables",
+ defaults: ["keystore_defaults"],
+ export_include_dirs: ["include"],
+ srcs: [
+ "KeyAttestationApplicationId.cpp",
+ "KeyAttestationPackageInfo.cpp",
+ "KeymasterArguments.cpp",
+ "KeystoreArguments.cpp",
+ "OperationResult.cpp",
+ "Signature.cpp",
+ "keystore_aidl_hidl_marshalling_utils.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.keymaster@3.0",
+ "libbinder",
+ "libhardware",
+ "libhidlbase",
+ "libhwbinder",
+ "liblog",
+ "libprotobuf-cpp-lite",
+ "libutils",
+ ],
+ export_shared_lib_headers: [
+ "android.hardware.keymaster@3.0",
+ "libbinder",
+ "libhidlbase",
+ "libhwbinder",
+ ],
+}
// Library for keystore clients
cc_library_shared {
name: "libkeystore_binder",
defaults: ["keystore_defaults"],
srcs: [
- "IKeystoreService.cpp",
- "KeyAttestationApplicationId.cpp",
- "KeyAttestationPackageInfo.cpp",
- "Signature.cpp",
"authorization_set.cpp",
"keyblob_utils.cpp",
- "keystore_aidl_hidl_marshalling_utils.cpp",
"keystore_client.proto",
"keystore_client_impl.cpp",
"keystore_get.cpp",
@@ -134,6 +164,8 @@
"libhidlbase",
"libhwbinder",
"liblog",
+ "libkeystore_aidl",
+ "libkeystore_parcelables",
"libprotobuf-cpp-lite",
"libutils",
],
@@ -142,12 +174,18 @@
type: "lite",
export_proto_headers: true,
},
+ aidl: {
+ export_aidl_headers: true,
+ include_dirs: ["frameworks/base/core/java/"],
+ },
export_include_dirs: ["include"],
export_shared_lib_headers: [
"android.hardware.keymaster@3.0",
"libbinder",
"libhidlbase",
"libhwbinder",
+ "libkeystore_aidl",
+ "libkeystore_parcelables",
],
}
@@ -176,13 +214,15 @@
name: "libkeystore_test",
defaults: ["keystore_defaults"],
- srcs: ["auth_token_table.cpp"],
+ srcs: [
+ "auth_token_table.cpp",
+ "authorization_set.cpp",
+ ],
static_libs: ["libgtest_main"],
shared_libs: [
"android.hardware.keymaster@3.0",
"libhidlbase",
"libhwbinder",
- "libkeymaster_messages",
"libutils",
],
export_shared_lib_headers: [
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
deleted file mode 100644
index eee9942..0000000
--- a/keystore/IKeystoreService.cpp
+++ /dev/null
@@ -1,1361 +0,0 @@
-/*
-**
-** Copyright 2008, 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 <stdint.h>
-#include <sys/limits.h>
-#include <sys/types.h>
-
-#include <algorithm>
-#include <limits>
-
-#define LOG_TAG "KeystoreService"
-#include <utils/Log.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/Parcel.h>
-
-#include <keystore/IKeystoreService.h>
-#include <keystore/keystore_hidl_support.h>
-
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-namespace android {
-using namespace ::keystore;
-
-const ssize_t MAX_GENERATE_ARGS = 3;
-
-KeystoreArg::KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
-
-KeystoreArg::~KeystoreArg() {}
-
-const void* KeystoreArg::data() const {
- return mData;
-}
-
-size_t KeystoreArg::size() const {
- return mSize;
-}
-
-OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
-
-OperationResult::~OperationResult() {}
-
-status_t OperationResult::readFromParcel(const Parcel* inn) {
- const Parcel& in = *inn;
- resultCode = ErrorCode(in.readInt32());
- token = in.readStrongBinder();
- handle = static_cast<uint64_t>(in.readInt64());
- inputConsumed = in.readInt32();
- data = readKeymasterBlob(in);
- outParams = readParamSetFromParcel(in);
- return OK;
-}
-
-status_t OperationResult::writeToParcel(Parcel* out) const {
- out->writeInt32(resultCode);
- out->writeStrongBinder(token);
- out->writeInt64(handle);
- out->writeInt32(inputConsumed);
- writeKeymasterBlob(data, out);
- writeParamSetToParcel(outParams, out);
- return OK;
-}
-
-ExportResult::ExportResult() : resultCode() {}
-
-ExportResult::~ExportResult() {}
-
-status_t ExportResult::readFromParcel(const Parcel* inn) {
- const Parcel& in = *inn;
- resultCode = ErrorCode(in.readInt32());
- exportData = readKeymasterBlob(in);
- return OK;
-}
-
-status_t ExportResult::writeToParcel(Parcel* out) const {
- out->writeInt32(resultCode);
- writeKeymasterBlob(exportData, out);
- return OK;
-}
-
-/**
- * Read a byte array from in. The data at *data is still owned by the parcel
- */
-static void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) {
- ssize_t slength = in.readInt32();
- if (slength > 0) {
- *data = reinterpret_cast<const uint8_t*>(in.readInplace(slength));
- if (*data) {
- *length = static_cast<size_t>(slength);
- } else {
- *length = 0;
- }
- } else {
- *data = NULL;
- *length = 0;
- }
-}
-
-class BpKeystoreService : public BpInterface<IKeystoreService> {
- public:
- explicit BpKeystoreService(const sp<IBinder>& impl) : BpInterface<IKeystoreService>(impl) {}
-
- // test ping
- KeyStoreServiceReturnCode getState(int32_t userId) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("getState() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("getState() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ret;
- }
-
- KeyStoreServiceReturnCode get(const String16& name, int32_t uid,
- hidl_vec<uint8_t>* item) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("get() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("get() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- auto resultItem = readBlobAsByteArray(reply);
- if (item) *item = resultItem.value();
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode insert(const String16& name, const hidl_vec<uint8_t>& item, int uid,
- int32_t flags) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- writeBlobAsByteArray(item, &data);
- data.writeInt32(uid);
- data.writeInt32(flags);
- status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("import() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("import() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode del(const String16& name, int uid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("del() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("del() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode exist(const String16& name, int uid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("exist() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("exist() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode list(const String16& prefix, int uid,
- Vector<String16>* matches) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(prefix);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("list() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- int32_t numMatches = reply.readInt32();
- for (int32_t i = 0; i < numMatches; i++) {
- matches->push(reply.readString16());
- }
- if (err < 0) {
- ALOGD("list() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode reset() override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("reset() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("reset() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
- const String16& password) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- data.writeString16(password);
- status_t status =
- remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("onUserPasswordChanged() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode lock(int32_t userId) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("lock() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("lock() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode unlock(int32_t userId, const String16& password) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- data.writeString16(password);
- status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("unlock() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("unlock() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- bool isEmpty(int32_t userId) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- status_t status = remote()->transact(BnKeystoreService::IS_EMPTY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("isEmpty() could not contact remote: %d\n", status);
- return false;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("isEmpty() caught exception %d\n", err);
- return false;
- }
- return reply.readInt32() != 0;
- }
-
- KeyStoreServiceReturnCode generate(const String16& name, int32_t uid, int32_t keyType,
- int32_t keySize, int32_t flags,
- Vector<sp<KeystoreArg>>* args) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(uid);
- data.writeInt32(keyType);
- data.writeInt32(keySize);
- data.writeInt32(flags);
- data.writeInt32(1);
- data.writeInt32(args->size());
- for (Vector<sp<KeystoreArg>>::iterator it = args->begin(); it != args->end(); ++it) {
- sp<KeystoreArg> item = *it;
- size_t keyLength = item->size();
- data.writeInt32(keyLength);
- void* buf = data.writeInplace(keyLength);
- memcpy(buf, item->data(), keyLength);
- }
- status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("generate() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("generate() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode import(const String16& name, const hidl_vec<uint8_t>& key, int uid,
- int flags) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- writeBlobAsByteArray(key, &data);
- data.writeInt32(uid);
- data.writeInt32(flags);
- status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("import() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("import() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode sign(const String16& name, const hidl_vec<uint8_t>& in,
- hidl_vec<uint8_t>* out) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- writeBlobAsByteArray(in, &data);
- status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("import() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("import() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- auto outBlob = readBlobAsByteArray(reply);
- if (out) {
- // don't need to check outBlob.isOk()
- // if !outBlob.isOk() the wrapped value is default constructed and therefore empty,
- // as expected.
- *out = outBlob.value();
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode verify(const String16& name, const hidl_vec<uint8_t>& in,
- const hidl_vec<uint8_t>& signature) override {
- Parcel data, reply;
-
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- writeBlobAsByteArray(in, &data);
- writeBlobAsByteArray(signature, &data);
- status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("verify() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("verify() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode get_pubkey(const String16& name, hidl_vec<uint8_t>* pubkey) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("get_pubkey() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("get_pubkey() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- auto resultKey = readBlobAsByteArray(reply);
- if (pubkey) *pubkey = resultKey.value();
- return ResponseCode(reply.readInt32());
- }
-
- String16 grant(const String16& name, int32_t granteeUid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(granteeUid);
- status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("grant() could not contact remote: %d\n", status);
- return String16();
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("grant() caught exception %d\n", err);
- return String16();
- }
- return reply.readString16();
- }
-
- KeyStoreServiceReturnCode ungrant(const String16& name, int32_t granteeUid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(granteeUid);
- status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("ungrant() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("ungrant() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- int64_t getmtime(const String16& name, int32_t uid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("getmtime() could not contact remote: %d\n", status);
- return -1;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("getmtime() caught exception %d\n", err);
- return -1;
- }
- return reply.readInt64();
- }
-
- KeyStoreServiceReturnCode duplicate(const String16& srcKey, int32_t srcUid,
- const String16& destKey, int32_t destUid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(srcKey);
- data.writeInt32(srcUid);
- data.writeString16(destKey);
- data.writeInt32(destUid);
- status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("duplicate() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("duplicate() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- int32_t is_hardware_backed(const String16& keyType) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(keyType);
- status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
- return -1;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("is_hardware_backed() caught exception %d\n", err);
- return -1;
- }
- return reply.readInt32();
- }
-
- KeyStoreServiceReturnCode clear_uid(int64_t uid) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt64(uid);
- status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("clear_uid() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("clear_uid() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- writeBlobAsByteArray(entropy, &data);
- status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("addRngEntropy() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("addRngEntropy() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- };
-
- KeyStoreServiceReturnCode generateKey(const String16& name,
- const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int uid, int flags,
- KeyCharacteristics* outCharacteristics) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- nullable(writeParamSetToParcel, params, &data);
- writeBlobAsByteArray(entropy, &data);
- data.writeInt32(uid);
- data.writeInt32(flags);
- status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("generateKey() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("generateKey() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- if (outCharacteristics) {
- *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
- }
- return ret;
- }
- KeyStoreServiceReturnCode
- getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
- const hidl_vec<uint8_t>& appData, int32_t uid,
- KeyCharacteristics* outCharacteristics) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- writeBlobAsByteArray(clientId, &data);
- writeBlobAsByteArray(appData, &data);
- data.writeInt32(uid);
- status_t status =
- remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("getKeyCharacteristics() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- if (outCharacteristics) {
- *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
- }
- return ret;
- }
- KeyStoreServiceReturnCode importKey(const String16& name, const hidl_vec<KeyParameter>& params,
- KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid,
- int flags,
- KeyCharacteristics* outCharacteristics) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- nullable(writeParamSetToParcel, params, &data);
- data.writeInt32(uint32_t(format));
- writeBlobAsByteArray(keyData, &data);
- data.writeInt32(uid);
- data.writeInt32(flags);
- status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("importKey() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("importKey() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- if (outCharacteristics) {
- *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
- }
- return ret;
- }
-
- void exportKey(const String16& name, KeyFormat format, const hidl_vec<uint8_t>& clientId,
- const hidl_vec<uint8_t>& appData, int32_t uid, ExportResult* result) override {
- if (!result) {
- return;
- }
-
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeInt32(int32_t(format));
- writeBlobAsByteArray(clientId, &data);
- writeBlobAsByteArray(appData, &data);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("exportKey() could not contact remote: %d\n", status);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("exportKey() caught exception %d\n", err);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
-
- reply.readParcelable(result);
- }
-
- void begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
- bool pruneable, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int32_t uid, OperationResult* result) override {
- if (!result) {
- return;
- }
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeStrongBinder(appToken);
- data.writeString16(name);
- data.writeInt32(int32_t(purpose));
- data.writeInt32(pruneable ? 1 : 0);
- nullable(writeParamSetToParcel, params, &data);
- writeBlobAsByteArray(entropy, &data);
- data.writeInt32(uid);
- status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("begin() could not contact remote: %d\n", status);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("begin() caught exception %d\n", err);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
-
- reply.readParcelable(result);
- }
-
- void update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& opData, OperationResult* result) override {
- if (!result) {
- return;
- }
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeStrongBinder(token);
- nullable(writeParamSetToParcel, params, &data);
- writeBlobAsByteArray(opData, &data);
- status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("update() could not contact remote: %d\n", status);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("update() caught exception %d\n", err);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
-
- reply.readParcelable(result);
- }
-
- void finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
- OperationResult* result) override {
- if (!result) {
- return;
- }
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeStrongBinder(token);
- nullable(writeParamSetToParcel, params, &data);
- writeBlobAsByteArray(signature, &data);
- writeBlobAsByteArray(entropy, &data);
- status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("finish() could not contact remote: %d\n", status);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("finish() caught exception %d\n", err);
- result->resultCode = ResponseCode::SYSTEM_ERROR;
- return;
- }
-
- reply.readParcelable(result);
- }
-
- KeyStoreServiceReturnCode abort(const sp<IBinder>& token) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeStrongBinder(token);
- status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("abort() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("abort() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- bool isOperationAuthorized(const sp<IBinder>& token) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeStrongBinder(token);
- status_t status =
- remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("isOperationAuthorized() could not contact remote: %d\n", status);
- return false;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("isOperationAuthorized() caught exception %d\n", err);
- return false;
- }
- return reply.readInt32() == 1;
- }
-
- KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeByteArray(length, token);
- status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("addAuthToken() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("addAuthToken() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- };
-
- KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- data.writeInt32(parentId);
- status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("onUserAdded() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("onUserAdded() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeInt32(userId);
- status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("onUserRemoved() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("onUserRemoved() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-
- KeyStoreServiceReturnCode attestKey(const String16& name, const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) override {
- if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL;
-
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- data.writeString16(name);
- nullable(writeParamSetToParcel, params, &data);
-
- status_t status = remote()->transact(BnKeystoreService::ATTEST_KEY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("attestkey() count not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("attestKey() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- if (reply.readInt32() != 0) {
- *outChain = readCertificateChainFromParcel(reply);
- }
- return ret;
- }
-
- KeyStoreServiceReturnCode attestDeviceIds(const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) override {
- if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL;
-
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- nullable(writeParamSetToParcel, params, &data);
-
- status_t status = remote()->transact(BnKeystoreService::ATTEST_DEVICE_IDS, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("attestDeviceIds() count not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- ResponseCode ret = ResponseCode(reply.readInt32());
- if (err < 0) {
- ALOGD("attestDeviceIds() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- if (reply.readInt32() != 0) {
- *outChain = readCertificateChainFromParcel(reply);
- }
- return ret;
- }
-
- KeyStoreServiceReturnCode onDeviceOffBody() override {
- Parcel data, reply;
- data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
- status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply);
- if (status != NO_ERROR) {
- ALOGD("onDeviceOffBody() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
- }
- int32_t err = reply.readExceptionCode();
- if (err < 0) {
- ALOGD("onDeviceOffBody() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
- }
- return ResponseCode(reply.readInt32());
- }
-};
-
-IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
-
-// ----------------------------------------------------------------------
-
-status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags) {
- switch (code) {
- case GET_STATE: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- int32_t ret = getState(userId);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case GET: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int32_t uid = data.readInt32();
- hidl_vec<uint8_t> out;
- auto ret = get(name, uid, &out);
- reply->writeNoException();
- if (ret.isOk()) {
- writeBlobAsByteArray(out, reply);
- } else {
- reply->writeInt32(-1);
- }
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case INSERT: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto in = readBlobAsByteArray(data);
- int uid = data.readInt32();
- int32_t flags = data.readInt32();
- int32_t ret = insert(name, in.value(), uid, flags);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case DEL: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int uid = data.readInt32();
- int32_t ret = del(name, uid);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case EXIST: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int uid = data.readInt32();
- int32_t ret = exist(name, uid);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case LIST: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 prefix = data.readString16();
- int uid = data.readInt32();
- Vector<String16> matches;
- int32_t ret = list(prefix, uid, &matches);
- reply->writeNoException();
- reply->writeInt32(matches.size());
- Vector<String16>::const_iterator it = matches.begin();
- for (; it != matches.end(); ++it) {
- reply->writeString16(*it);
- }
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case RESET: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t ret = reset();
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case ON_USER_PASSWORD_CHANGED: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- String16 pass = data.readString16();
- int32_t ret = onUserPasswordChanged(userId, pass);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case LOCK: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- int32_t ret = lock(userId);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case UNLOCK: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- String16 pass = data.readString16();
- int32_t ret = unlock(userId, pass);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case IS_EMPTY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- bool ret = isEmpty(userId);
- reply->writeNoException();
- reply->writeInt32(ret ? 1 : 0);
- return NO_ERROR;
- } break;
- case GENERATE: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int32_t uid = data.readInt32();
- int32_t keyType = data.readInt32();
- int32_t keySize = data.readInt32();
- int32_t flags = data.readInt32();
- Vector<sp<KeystoreArg>> args;
- int32_t argsPresent = data.readInt32();
- if (argsPresent == 1) {
- ssize_t numArgs = data.readInt32();
- if (numArgs > MAX_GENERATE_ARGS) {
- return BAD_VALUE;
- }
- if (numArgs > 0) {
- for (size_t i = 0; i < (size_t)numArgs; i++) {
- ssize_t inSize = data.readInt32();
- if (inSize >= 0 && (size_t)inSize <= data.dataAvail()) {
- sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize);
- args.push_back(arg);
- } else {
- args.push_back(NULL);
- }
- }
- }
- }
- int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case IMPORT: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto in = readBlobAsByteArray(data);
- int uid = data.readInt32();
- int32_t flags = data.readInt32();
- auto ret = import(name, in.value(), uid, flags);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case SIGN: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto in = readBlobAsByteArray(data);
- hidl_vec<uint8_t> out;
- auto ret = sign(name, in.value(), &out);
- reply->writeNoException();
- writeBlobAsByteArray(out, reply);
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case VERIFY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto in = readBlobAsByteArray(data);
- auto signature = readBlobAsByteArray(data);
- auto ret = verify(name, in.value(), signature.value());
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case GET_PUBKEY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- hidl_vec<uint8_t> out;
- auto ret = get_pubkey(name, &out);
- reply->writeNoException();
- writeBlobAsByteArray(out, reply);
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case GRANT: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int32_t granteeUid = data.readInt32();
- String16 ret = grant(name, granteeUid);
- reply->writeNoException();
- reply->writeString16(ret);
- return NO_ERROR;
- } break;
- case UNGRANT: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int32_t granteeUid = data.readInt32();
- int32_t ret = ungrant(name, granteeUid);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case GETMTIME: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- int32_t uid = data.readInt32();
- int64_t ret = getmtime(name, uid);
- reply->writeNoException();
- reply->writeInt64(ret);
- return NO_ERROR;
- } break;
- case DUPLICATE: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 srcKey = data.readString16();
- int32_t srcUid = data.readInt32();
- String16 destKey = data.readString16();
- int32_t destUid = data.readInt32();
- int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- } break;
- case IS_HARDWARE_BACKED: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 keyType = data.readString16();
- int32_t ret = is_hardware_backed(keyType);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- }
- case CLEAR_UID: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int64_t uid = data.readInt64();
- int32_t ret = clear_uid(uid);
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- }
- case ADD_RNG_ENTROPY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- auto entropy = readBlobAsByteArray(data);
- auto ret = addRngEntropy(entropy.value());
- reply->writeNoException();
- reply->writeInt32(ret);
- return NO_ERROR;
- }
- case GENERATE_KEY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto params = nullable(readParamSetFromParcel, data);
- auto entropy = readBlobAsByteArray(data);
- int32_t uid = data.readInt32();
- int32_t flags = data.readInt32();
- KeyCharacteristics outCharacteristics;
- int32_t ret =
- generateKey(name, params.value(), entropy.value(), uid, flags, &outCharacteristics);
- reply->writeNoException();
- reply->writeInt32(ret);
- nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
- return NO_ERROR;
- }
- case GET_KEY_CHARACTERISTICS: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto clientId = nullable(readKeymasterBlob, data, true);
- auto appData = nullable(readKeymasterBlob, data, true);
- int32_t uid = data.readInt32();
- KeyCharacteristics outCharacteristics;
- int ret = getKeyCharacteristics(name, clientId.value(), appData.value(), uid,
- &outCharacteristics);
- reply->writeNoException();
- reply->writeInt32(ret);
- nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
- return NO_ERROR;
- }
- case IMPORT_KEY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto args = nullable(readParamSetFromParcel, data);
- KeyFormat format = static_cast<KeyFormat>(data.readInt32());
- auto keyData = readBlobAsByteArray(data);
- int32_t uid = data.readInt32();
- int32_t flags = data.readInt32();
- KeyCharacteristics outCharacteristics;
- int32_t ret =
- importKey(name, args.value(), format, keyData.value(), uid, flags, &outCharacteristics);
- reply->writeNoException();
- reply->writeInt32(ret);
- nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
- return NO_ERROR;
- }
- case EXPORT_KEY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- KeyFormat format = static_cast<KeyFormat>(data.readInt32());
- auto clientId = nullable(readKeymasterBlob, data, true);
- auto appData = nullable(readKeymasterBlob, data, true);
- int32_t uid = data.readInt32();
- ExportResult result;
- exportKey(name, format, clientId.value(), appData.value(), uid, &result);
- reply->writeNoException();
- reply->writeParcelable(result);
-
- return NO_ERROR;
- }
- case BEGIN: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- sp<IBinder> token = data.readStrongBinder();
- String16 name = data.readString16();
- KeyPurpose purpose = static_cast<KeyPurpose>(data.readInt32());
- bool pruneable = data.readInt32() != 0;
- auto args = nullable(readParamSetFromParcel, data);
- auto entropy = readBlobAsByteArray(data);
- int32_t uid = data.readInt32();
- OperationResult result;
- begin(token, name, purpose, pruneable, args.value(), entropy.value(), uid, &result);
- reply->writeNoException();
- reply->writeParcelable(result);
-
- return NO_ERROR;
- }
- case UPDATE: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- sp<IBinder> token = data.readStrongBinder();
- auto args = nullable(readParamSetFromParcel, data);
- auto buf = readBlobAsByteArray(data);
- OperationResult result;
- update(token, args.value(), buf.value(), &result);
- reply->writeNoException();
- reply->writeParcelable(result);
-
- return NO_ERROR;
- }
- case FINISH: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- sp<IBinder> token = data.readStrongBinder();
- auto args = nullable(readParamSetFromParcel, data);
- auto signature = readBlobAsByteArray(data);
- auto entropy = readBlobAsByteArray(data);
- OperationResult result;
- finish(token, args.value(), signature.value(), entropy.value(), &result);
- reply->writeNoException();
- reply->writeParcelable(result);
-
- return NO_ERROR;
- }
- case ABORT: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- sp<IBinder> token = data.readStrongBinder();
- int32_t result = abort(token);
- reply->writeNoException();
- reply->writeInt32(result);
-
- return NO_ERROR;
- }
- case IS_OPERATION_AUTHORIZED: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- sp<IBinder> token = data.readStrongBinder();
- bool result = isOperationAuthorized(token);
- reply->writeNoException();
- reply->writeInt32(result ? 1 : 0);
-
- return NO_ERROR;
- }
- case ADD_AUTH_TOKEN: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- const uint8_t* token_bytes = NULL;
- size_t size = 0;
- readByteArray(data, &token_bytes, &size);
- int32_t result = addAuthToken(token_bytes, size);
- reply->writeNoException();
- reply->writeInt32(result);
-
- return NO_ERROR;
- }
- case ON_USER_ADDED: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- int32_t parentId = data.readInt32();
- int32_t result = onUserAdded(userId, parentId);
- reply->writeNoException();
- reply->writeInt32(result);
-
- return NO_ERROR;
- }
- case ON_USER_REMOVED: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t userId = data.readInt32();
- int32_t result = onUserRemoved(userId);
- reply->writeNoException();
- reply->writeInt32(result);
-
- return NO_ERROR;
- }
- case ATTEST_KEY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- String16 name = data.readString16();
- auto params = nullable(readParamSetFromParcel, data);
- hidl_vec<hidl_vec<uint8_t>> chain;
- int ret = attestKey(name, params.value(), &chain);
- reply->writeNoException();
- reply->writeInt32(ret);
- nullable(writeCertificateChainToParcel, chain, reply);
-
- return NO_ERROR;
- }
-
- case ATTEST_DEVICE_IDS: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- auto params = nullable(readParamSetFromParcel, data);
- hidl_vec<hidl_vec<uint8_t>> chain;
- int ret = attestDeviceIds(params.value(), &chain);
- reply->writeNoException();
- reply->writeInt32(ret);
- nullable(writeCertificateChainToParcel, chain, reply);
-
- return NO_ERROR;
- }
-
- case ON_DEVICE_OFF_BODY: {
- CHECK_INTERFACE(IKeystoreService, data, reply);
- int32_t ret = onDeviceOffBody();
- reply->writeNoException();
- reply->writeInt32(ret);
-
- return NO_ERROR;
- }
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/keystore/KeymasterArguments.cpp b/keystore/KeymasterArguments.cpp
new file mode 100644
index 0000000..792c831
--- /dev/null
+++ b/keystore/KeymasterArguments.cpp
@@ -0,0 +1,42 @@
+/*
+**
+** 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/KeymasterArguments.h"
+#include "keystore_aidl_hidl_marshalling_utils.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+using ::android::status_t;
+status_t KeymasterArguments::readFromParcel(const android::Parcel* in) {
+ data_ = keystore::readParamSetFromParcel(*in);
+ return OK;
+};
+
+status_t KeymasterArguments::writeToParcel(android::Parcel* out) const {
+ return keystore::writeParamSetToParcel(data_, out);
+};
+
+KeymasterArguments::KeymasterArguments(const hardware::hidl_vec<keymaster::KeyParameter>& other)
+ : data_(other) {}
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
diff --git a/keystore/KeystoreArguments.cpp b/keystore/KeystoreArguments.cpp
new file mode 100644
index 0000000..fe53c29
--- /dev/null
+++ b/keystore/KeystoreArguments.cpp
@@ -0,0 +1,61 @@
+/*
+**
+** 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(NULL);
+ }
+ }
+ }
+ return OK;
+};
+
+status_t KeystoreArguments::writeToParcel(android::Parcel* out) const {
+ out->writeInt32(args.size());
+ for (sp<KeystoreArg> item : args) {
+ size_t keyLength = item->size();
+ out->writeInt32(keyLength);
+ void* buf = out->writeInplace(keyLength);
+ memcpy(buf, item->data(), keyLength);
+ }
+ return OK;
+}
+
+} // namespace security
+} // namespace android
diff --git a/keystore/OperationResult.cpp b/keystore/OperationResult.cpp
new file mode 100644
index 0000000..f7f33f9
--- /dev/null
+++ b/keystore/OperationResult.cpp
@@ -0,0 +1,58 @@
+/*
+**
+** 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/OperationResult.h"
+
+#include <binder/Parcel.h>
+#include <utility>
+
+#include "keystore_aidl_hidl_marshalling_utils.h"
+#include <keystore/keymaster_tags.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::status_t;
+
+OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
+
+status_t OperationResult::readFromParcel(const Parcel* inn) {
+ const Parcel& in = *inn;
+ resultCode = ErrorCode(in.readInt32());
+ token = in.readStrongBinder();
+ handle = static_cast<uint64_t>(in.readInt64());
+ inputConsumed = in.readInt32();
+ data = keystore::readKeymasterBlob(in);
+ outParams = keystore::readParamSetFromParcel(in);
+ return OK;
+}
+
+status_t OperationResult::writeToParcel(Parcel* out) const {
+ out->writeInt32(resultCode);
+ out->writeStrongBinder(token);
+ out->writeInt64(handle);
+ out->writeInt32(inputConsumed);
+ keystore::writeKeymasterBlob(data, out);
+ keystore::writeParamSetToParcel(outParams, out);
+ return OK;
+}
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index 46b644d..e54febe 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -77,12 +77,12 @@
return time.tv_sec;
}
-void AuthTokenTable::AddAuthenticationToken(const HardwareAuthToken* auth_token) {
- Entry new_entry(auth_token, clock_function_());
+void AuthTokenTable::AddAuthenticationToken(std::unique_ptr<const HardwareAuthToken>&& auth_token) {
+ Entry new_entry(std::move(auth_token), clock_function_());
//STOPSHIP: debug only, to be removed
ALOGD("AddAuthenticationToken: timestamp = %llu (%llu), time_received = %lld",
static_cast<unsigned long long>(new_entry.timestamp_host_order()),
- static_cast<unsigned long long>(auth_token->timestamp),
+ static_cast<unsigned long long>(new_entry.token().timestamp),
static_cast<long long>(new_entry.time_received()));
RemoveEntriesSupersededBy(new_entry);
@@ -137,13 +137,13 @@
if (op_handle == 0) return OP_HANDLE_REQUIRED;
auto matching_op = find_if(
- entries_, [&](Entry& e) { return e.token()->challenge == op_handle && !e.completed(); });
+ entries_, [&](Entry& e) { return e.token().challenge == op_handle && !e.completed(); });
if (matching_op == entries_.end()) return AUTH_TOKEN_NOT_FOUND;
if (!matching_op->SatisfiesAuth(sids, auth_type)) return AUTH_TOKEN_WRONG_SID;
- *found = matching_op->token();
+ *found = &matching_op->token();
return OK;
}
@@ -172,7 +172,7 @@
}
newest_match->UpdateLastUse(now);
- *found = newest_match->token();
+ *found = &newest_match->token();
return OK;
}
@@ -202,7 +202,7 @@
}
void AuthTokenTable::MarkCompleted(const uint64_t op_handle) {
- auto found = find_if(entries_, [&](Entry& e) { return e.token()->challenge == op_handle; });
+ auto found = find_if(entries_, [&](Entry& e) { return e.token().challenge == op_handle; });
if (found == entries_.end()) return;
assert(!IsSupersededBySomeEntry(*found));
@@ -211,8 +211,8 @@
if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
}
-AuthTokenTable::Entry::Entry(const HardwareAuthToken* token, time_t current_time)
- : token_(token), time_received_(current_time), last_use_(current_time),
+AuthTokenTable::Entry::Entry(std::unique_ptr<const HardwareAuthToken>&& token, time_t current_time)
+ : token_(std::move(token)), time_received_(current_time), last_use_(current_time),
operation_completed_(token_->challenge == 0) {}
uint64_t AuthTokenTable::Entry::timestamp_host_order() const {
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 0056b26..3e3ff6e 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -17,7 +17,6 @@
#include <memory>
#include <vector>
-#include <hardware/hw_auth_token.h>
#include <keystore/authorization_set.h>
#ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
@@ -61,7 +60,7 @@
/**
* Add an authorization token to the table. The table takes ownership of the argument.
*/
- void AddAuthenticationToken(const HardwareAuthToken* token);
+ void AddAuthenticationToken(std::unique_ptr<const HardwareAuthToken>&& auth_token);
/**
* Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -97,7 +96,7 @@
class Entry {
public:
- Entry(const HardwareAuthToken* token, time_t current_time);
+ Entry(std::unique_ptr<const HardwareAuthToken>&& token, time_t current_time);
Entry(Entry&& entry) { *this = std::move(entry); }
void operator=(Entry&& rhs) {
@@ -127,7 +126,7 @@
void mark_completed() { operation_completed_ = true; }
- const HardwareAuthToken* token() { return token_.get(); }
+ const HardwareAuthToken& token() { return *token_.get(); }
time_t time_received() const { return time_received_; }
bool completed() const { return operation_completed_; }
uint64_t timestamp_host_order() const;
diff --git a/keystore/include/keystore/ExportResult.h b/keystore/include/keystore/ExportResult.h
new file mode 100644
index 0000000..c85f5ab
--- /dev/null
+++ b/keystore/include/keystore/ExportResult.h
@@ -0,0 +1,47 @@
+// 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_EXPORTRESULT_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_EXPORTRESULT_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include <binder/Parcelable.h>
+#include <hardware/keymaster_defs.h>
+
+#include "keystore_return_types.h"
+#include "utils.h"
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+struct ExportResult : public ::android::Parcelable {
+ ExportResult();
+ ~ExportResult();
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ ::keystore::KeyStoreServiceReturnCode resultCode;
+ hardware::hidl_vec<uint8_t> exportData;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_EXPORTRESULT_H_
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
deleted file mode 100644
index a045679..0000000
--- a/keystore/include/keystore/IKeystoreService.h
+++ /dev/null
@@ -1,254 +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_IKEYSTORESERVICE_H
-#define KEYSTORE_IKEYSTORESERVICE_H
-
-#include "keystore.h"
-#include "keystore_return_types.h"
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <keystore/keymaster_tags.h>
-#include <utils/RefBase.h>
-#include <vector>
-
-namespace android {
-
-class KeystoreArg : public RefBase {
- public:
- KeystoreArg(const void* data, size_t len);
- ~KeystoreArg();
-
- const void* data() const;
- size_t size() const;
-
- private:
- const void* mData;
- size_t mSize;
-};
-
-struct MallocDeleter {
- void operator()(uint8_t* p) { free(p); }
-};
-
-// struct for serializing the results of begin/update/finish
-struct OperationResult : public ::android::Parcelable {
- OperationResult();
- ~OperationResult();
- status_t readFromParcel(const Parcel* in) override;
- status_t writeToParcel(Parcel* out) const override;
-
- ::keystore::KeyStoreServiceReturnCode resultCode;
- sp<IBinder> token;
- uint64_t handle;
- int inputConsumed;
- ::keystore::hidl_vec<uint8_t> data;
- ::keystore::hidl_vec<::keystore::KeyParameter> outParams;
-};
-
-// struct for serializing the results of export
-struct ExportResult : public ::android::Parcelable {
- ExportResult();
- ~ExportResult();
- status_t readFromParcel(const Parcel* in) override;
- status_t writeToParcel(Parcel* out) const override;
-
- ::keystore::KeyStoreServiceReturnCode resultCode;
- ::keystore::hidl_vec<uint8_t> exportData;
-};
-
-/*
- * This must be kept manually in sync with frameworks/base's IKeystoreService.java
- */
-class IKeystoreService : public IInterface {
- public:
- enum {
- GET_STATE = IBinder::FIRST_CALL_TRANSACTION + 0,
- GET = IBinder::FIRST_CALL_TRANSACTION + 1,
- INSERT = IBinder::FIRST_CALL_TRANSACTION + 2,
- DEL = IBinder::FIRST_CALL_TRANSACTION + 3,
- EXIST = IBinder::FIRST_CALL_TRANSACTION + 4,
- LIST = IBinder::FIRST_CALL_TRANSACTION + 5,
- RESET = IBinder::FIRST_CALL_TRANSACTION + 6,
- ON_USER_PASSWORD_CHANGED = IBinder::FIRST_CALL_TRANSACTION + 7,
- LOCK = IBinder::FIRST_CALL_TRANSACTION + 8,
- UNLOCK = IBinder::FIRST_CALL_TRANSACTION + 9,
- IS_EMPTY = IBinder::FIRST_CALL_TRANSACTION + 10,
- GENERATE = IBinder::FIRST_CALL_TRANSACTION + 11,
- IMPORT = IBinder::FIRST_CALL_TRANSACTION + 12,
- SIGN = IBinder::FIRST_CALL_TRANSACTION + 13,
- VERIFY = IBinder::FIRST_CALL_TRANSACTION + 14,
- GET_PUBKEY = IBinder::FIRST_CALL_TRANSACTION + 15,
- GRANT = IBinder::FIRST_CALL_TRANSACTION + 16,
- UNGRANT = IBinder::FIRST_CALL_TRANSACTION + 17,
- GETMTIME = IBinder::FIRST_CALL_TRANSACTION + 18,
- DUPLICATE = IBinder::FIRST_CALL_TRANSACTION + 19,
- IS_HARDWARE_BACKED = IBinder::FIRST_CALL_TRANSACTION + 20,
- CLEAR_UID = IBinder::FIRST_CALL_TRANSACTION + 21,
- ADD_RNG_ENTROPY = IBinder::FIRST_CALL_TRANSACTION + 22,
- GENERATE_KEY = IBinder::FIRST_CALL_TRANSACTION + 23,
- GET_KEY_CHARACTERISTICS = IBinder::FIRST_CALL_TRANSACTION + 24,
- IMPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 25,
- EXPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 26,
- BEGIN = IBinder::FIRST_CALL_TRANSACTION + 27,
- UPDATE = IBinder::FIRST_CALL_TRANSACTION + 28,
- FINISH = IBinder::FIRST_CALL_TRANSACTION + 29,
- ABORT = IBinder::FIRST_CALL_TRANSACTION + 30,
- IS_OPERATION_AUTHORIZED = IBinder::FIRST_CALL_TRANSACTION + 31,
- ADD_AUTH_TOKEN = IBinder::FIRST_CALL_TRANSACTION + 32,
- ON_USER_ADDED = IBinder::FIRST_CALL_TRANSACTION + 33,
- ON_USER_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 34,
- ATTEST_KEY = IBinder::FIRST_CALL_TRANSACTION + 35,
- ATTEST_DEVICE_IDS = IBinder::FIRST_CALL_TRANSACTION + 36,
- ON_DEVICE_OFF_BODY = IBinder::FIRST_CALL_TRANSACTION + 37,
- };
-
- DECLARE_META_INTERFACE(KeystoreService);
-
- virtual ::keystore::KeyStoreServiceReturnCode getState(int32_t userId) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode get(const String16& name, int32_t uid,
- ::keystore::hidl_vec<uint8_t>* item) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode insert(const String16& name,
- const ::keystore::hidl_vec<uint8_t>& item,
- int uid, int32_t flags) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode del(const String16& name, int uid) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode exist(const String16& name, int uid) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode list(const String16& prefix, int uid,
- Vector<String16>* matches) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode reset() = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- onUserPasswordChanged(int32_t userId, const String16& newPassword) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode lock(int32_t userId) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode unlock(int32_t userId,
- const String16& password) = 0;
-
- virtual bool isEmpty(int32_t userId) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode generate(const String16& name, int32_t uid,
- int32_t keyType, int32_t keySize,
- int32_t flags,
- Vector<sp<KeystoreArg>>* args) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode import(const String16& name,
- const ::keystore::hidl_vec<uint8_t>& data,
- int uid, int32_t flags) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode sign(const String16& name,
- const ::keystore::hidl_vec<uint8_t>& data,
- ::keystore::hidl_vec<uint8_t>* out) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- verify(const String16& name, const ::keystore::hidl_vec<uint8_t>& data,
- const ::keystore::hidl_vec<uint8_t>& signature) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- get_pubkey(const String16& name, ::keystore::hidl_vec<uint8_t>* pubKey) = 0;
-
- virtual String16 grant(const String16& name, int32_t granteeUid) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode ungrant(const String16& name,
- int32_t granteeUid) = 0;
-
- virtual int64_t getmtime(const String16& name, int32_t uid) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) = 0;
-
- virtual int32_t is_hardware_backed(const String16& keyType) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode clear_uid(int64_t uid) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- addRngEntropy(const ::keystore::hidl_vec<uint8_t>& entropy) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- generateKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- const ::keystore::hidl_vec<uint8_t>& entropy, int uid, int flags,
- ::keystore::KeyCharacteristics* outCharacteristics) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- getKeyCharacteristics(const String16& name, const ::keystore::hidl_vec<uint8_t>& clientId,
- const ::keystore::hidl_vec<uint8_t>& appData, int32_t uid,
- ::keystore::KeyCharacteristics* outCharacteristics) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- importKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- ::keystore::KeyFormat format, const ::keystore::hidl_vec<uint8_t>& key, int uid,
- int flags, ::keystore::KeyCharacteristics* outCharacteristics) = 0;
-
- virtual void exportKey(const String16& name, ::keystore::KeyFormat format,
- const ::keystore::hidl_vec<uint8_t>& clientId,
- const ::keystore::hidl_vec<uint8_t>& appData, int uid,
- ExportResult* result) = 0;
-
- virtual void begin(const sp<IBinder>& apptoken, const String16& name,
- ::keystore::KeyPurpose purpose, bool pruneable,
- const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- const ::keystore::hidl_vec<uint8_t>& entropy, int32_t uid,
- OperationResult* opResult) = 0;
-
- virtual void update(const sp<IBinder>& token,
- const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- const ::keystore::hidl_vec<uint8_t>& data, OperationResult* opResult) = 0;
-
- virtual void finish(const sp<IBinder>& token,
- const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- const ::keystore::hidl_vec<uint8_t>& signature,
- const ::keystore::hidl_vec<uint8_t>& entropy,
- OperationResult* opResult) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode abort(const sp<IBinder>& handle) = 0;
-
- virtual bool isOperationAuthorized(const sp<IBinder>& handle) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode addAuthToken(const uint8_t* token,
- size_t length) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode onUserRemoved(int32_t userId) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode
- attestKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- ::keystore::hidl_vec<::keystore::hidl_vec<uint8_t>>* outChain) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode attestDeviceIds(
- const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
- ::keystore::hidl_vec<::keystore::hidl_vec<uint8_t>>* outChain) = 0;
-
- virtual ::keystore::KeyStoreServiceReturnCode onDeviceOffBody() = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnKeystoreService : public BnInterface<IKeystoreService> {
- public:
- virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags = 0);
-};
-
-} // namespace android
-
-#endif
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
index a7ce210..5161d4b 100644
--- a/keystore/include/keystore/KeyAttestationApplicationId.h
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -15,12 +15,13 @@
#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
-#include "KeyAttestationPackageInfo.h"
#include "utils.h"
#include <binder/Parcelable.h>
#include <memory>
#include <vector>
+#include "KeyAttestationPackageInfo.h"
+
namespace android {
namespace security {
namespace keymaster {
@@ -46,6 +47,6 @@
} // namespace keymaster
} // namespace security
-} // namsepace android
+} // namespace android
#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
diff --git a/keystore/include/keystore/KeyCharacteristics.h b/keystore/include/keystore/KeyCharacteristics.h
new file mode 100644
index 0000000..c1bffb2
--- /dev/null
+++ b/keystore/include/keystore/KeyCharacteristics.h
@@ -0,0 +1,47 @@
+// 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_KEYCHARACTERISTICS_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYCHARACTERISTICS_H_
+
+#include <binder/Parcelable.h>
+#include <hardware/keymaster_defs.h>
+
+#include "KeymasterArguments.h"
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+using hardware::keymaster::V3_0::KeyParameter;
+
+// Parcelable version of hardware::keymaster::V3_0::KeyCharacteristics
+struct KeyCharacteristics : public ::android::Parcelable {
+ KeyCharacteristics(){};
+ explicit KeyCharacteristics(const android::hardware::keymaster::V3_0::KeyCharacteristics& other) {
+ softwareEnforced = KeymasterArguments(other.softwareEnforced);
+ teeEnforced = KeymasterArguments(other.teeEnforced);
+ }
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ KeymasterArguments softwareEnforced;
+ KeymasterArguments teeEnforced;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYCHARACTERISTICS_H_
diff --git a/keystore/include/keystore/KeymasterArguments.h b/keystore/include/keystore/KeymasterArguments.h
new file mode 100644
index 0000000..0e7e64d
--- /dev/null
+++ b/keystore/include/keystore/KeymasterArguments.h
@@ -0,0 +1,45 @@
+// 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_KEYMASTERARGUMENTS_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERARGUMENTS_H_
+
+#include "authorization_set.h"
+#include <binder/Parcelable.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+using hardware::keymaster::V3_0::KeyParameter;
+
+// struct for serializing/deserializing a list of KeyParameter's
+struct KeymasterArguments : public Parcelable {
+ KeymasterArguments(){};
+ explicit KeymasterArguments(const hardware::hidl_vec<KeyParameter>& other);
+
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ const inline hardware::hidl_vec<KeyParameter>& getParameters() const { return data_; }
+
+ private:
+ hardware::hidl_vec<KeyParameter> data_;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERARGUMENTS_H_
diff --git a/keystore/include/keystore/KeymasterBlob.h b/keystore/include/keystore/KeymasterBlob.h
new file mode 100644
index 0000000..47cb7ee
--- /dev/null
+++ b/keystore/include/keystore/KeymasterBlob.h
@@ -0,0 +1,42 @@
+// 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_KEYMASTERBLOB_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERBLOB_H_
+
+#include "authorization_set.h"
+#include <binder/Parcelable.h>
+#include <hardware/keymaster_defs.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+// Parcelable which wraps hardware::hidl_vec<uint8_t>
+struct KeymasterBlob : public ::android::Parcelable {
+ KeymasterBlob(){};
+ explicit KeymasterBlob(hardware::hidl_vec<uint8_t> data) : data_(data) {}
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+ const hardware::hidl_vec<uint8_t>& getData() const { return data_; }
+
+ private:
+ hardware::hidl_vec<uint8_t> data_;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERBLOB_H_
diff --git a/keystore/include/keystore/KeymasterCertificateChain.h b/keystore/include/keystore/KeymasterCertificateChain.h
new file mode 100644
index 0000000..8c0a6fc
--- /dev/null
+++ b/keystore/include/keystore/KeymasterCertificateChain.h
@@ -0,0 +1,44 @@
+// 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_KEYMASTERCERTIFICATECHAIN_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
+
+#include "authorization_set.h"
+#include <binder/Parcelable.h>
+#include <hardware/keymaster_defs.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+// struct for serializing keymaster_cert_chain_t's
+struct KeymasterCertificateChain : public ::android::Parcelable {
+ KeymasterCertificateChain(){};
+ explicit KeymasterCertificateChain(hardware::hidl_vec<hardware::hidl_vec<uint8_t>> other)
+ : chain(std::move(other)) {}
+
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ private:
+ // The structure is only used as output and doesn't have getter.
+ hardware::hidl_vec<hardware::hidl_vec<uint8_t>> chain;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYMASTERCERTIFICATECHAIN_H_
diff --git a/keystore/include/keystore/KeystoreArg.h b/keystore/include/keystore/KeystoreArg.h
new file mode 100644
index 0000000..31496f0
--- /dev/null
+++ b/keystore/include/keystore/KeystoreArg.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <vector>
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <keystore/keymaster_tags.h>
+#include <utils/RefBase.h>
+
+#include "keystore.h"
+#include "keystore_return_types.h"
+
+namespace android {
+namespace security {
+
+// Simple pair of generic pointer and length of corresponding data structure.
+class KeystoreArg : public RefBase {
+ public:
+ KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
+ ~KeystoreArg() {}
+
+ const void* data() const { return mData; }
+ size_t size() const { return mSize; }
+
+ private:
+ const void* mData; // provider of the data must handle memory clean-up.
+ size_t mSize;
+};
+
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARG_H
diff --git a/keystore/include/keystore/KeystoreArguments.h b/keystore/include/keystore/KeystoreArguments.h
new file mode 100644
index 0000000..a54a6d2
--- /dev/null
+++ b/keystore/include/keystore/KeystoreArguments.h
@@ -0,0 +1,39 @@
+// 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 "KeystoreArg.h"
+#include <binder/Parcelable.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace security {
+
+// Parcelable KeystoreArguments.java which simply holds byte[][].
+struct KeystoreArguments : public ::android::Parcelable, public RefBase {
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ const Vector<sp<KeystoreArg>>& getArguments() const { return args; }
+
+ private:
+ Vector<sp<KeystoreArg>> args;
+};
+
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_KEYSTOREARGUMENTS_H_
diff --git a/keystore/include/keystore/OperationResult.h b/keystore/include/keystore/OperationResult.h
new file mode 100644
index 0000000..ada88fe
--- /dev/null
+++ b/keystore/include/keystore/OperationResult.h
@@ -0,0 +1,45 @@
+// 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_OPERATIONRESULT_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_OPERATIONRESULT_H_
+
+#include "KeymasterArguments.h"
+#include "keystore_return_types.h"
+#include <binder/Parcelable.h>
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+struct OperationResult : public ::android::Parcelable {
+ OperationResult();
+ status_t readFromParcel(const Parcel* in) override;
+ status_t writeToParcel(Parcel* out) const override;
+
+ // Native code may need to use KeyStoreNativeReturnCode
+ ::keystore::KeyStoreServiceReturnCode resultCode;
+ sp<IBinder> token;
+ uint64_t handle;
+ int inputConsumed;
+ ::keystore::hidl_vec<uint8_t> data;
+ ::keystore::hidl_vec<::keystore::KeyParameter> outParams;
+};
+
+} // namespace keymaster
+} // namespace security
+} // namespace android
+
+#endif // KEYSTORE_INCLUDE_KEYSTORE_OPERATIONRESULT_H_
diff --git a/keystore/include/keystore/keymaster_tags.h b/keystore/include/keystore/keymaster_tags.h
index 05a33cd..1b3e71b 100644
--- a/keystore/include/keystore/keymaster_tags.h
+++ b/keystore/include/keystore/keymaster_tags.h
@@ -60,7 +60,6 @@
*/
#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
-#include <hardware/hw_auth_token.h>
#include <type_traits>
namespace keystore {
diff --git a/keystore/include/keystore/keystore.h b/keystore/include/keystore/keystore.h
index 7260363..cb64498 100644
--- a/keystore/include/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -26,6 +26,7 @@
STATE_UNINITIALIZED = 3,
};
+// must be in sync with KeyStore.java,
enum class ResponseCode: int32_t {
NO_ERROR = STATE_NO_ERROR, // 1
LOCKED = STATE_LOCKED, // 2
@@ -64,23 +65,4 @@
KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3,
};
-/**
- * Returns the size of the softkey magic header value for measuring
- * and allocating purposes.
- */
-size_t get_softkey_header_size();
-
-/**
- * Adds the magic softkey header to a key blob.
- *
- * Returns NULL if the destination array is too small. Otherwise it
- * returns the offset directly after the magic value.
- */
-uint8_t* add_softkey_header(uint8_t* key_blob, size_t key_blob_length);
-
-/**
- * Returns true if the key blob has a magic softkey header at the beginning.
- */
-bool is_softkey(const uint8_t* key_blob, const size_t key_blob_length);
-
#endif
diff --git a/keystore/include/keystore/keystore_client.h b/keystore/include/keystore/keystore_client.h
index 2ba7fd4..928b2e6 100644
--- a/keystore/include/keystore/keystore_client.h
+++ b/keystore/include/keystore/keystore_client.h
@@ -27,8 +27,6 @@
namespace keystore {
-
-
// An abstract class providing a convenient interface to keystore services. This
// interface is designed to:
// - hide details of the IPC mechanism (e.g. binder)
@@ -87,17 +85,18 @@
// Adds |entropy| to the random number generator. Returns KM_ERROR_OK on
// success and a Keystore ResponseCode or keymaster_error_t on failure.
- virtual KeyStoreNativeReturnCode addRandomNumberGeneratorEntropy(const std::string& entropy) = 0;
+ virtual KeyStoreNativeReturnCode
+ addRandomNumberGeneratorEntropy(const std::string& entropy) = 0;
// Generates a key according to the given |key_parameters| and stores it with
// the given |key_name|. The [hardware|software]_enforced_characteristics of
// the key are provided on success. Returns KM_ERROR_OK on success. Returns
// KM_ERROR_OK on success and a Keystore ResponseCode or keymaster_error_t on
// failure.
- virtual KeyStoreNativeReturnCode generateKey(const std::string& key_name,
- const keystore::AuthorizationSet& key_parameters,
- keystore::AuthorizationSet* hardware_enforced_characteristics,
- keystore::AuthorizationSet* software_enforced_characteristics) = 0;
+ virtual KeyStoreNativeReturnCode
+ generateKey(const std::string& key_name, const keystore::AuthorizationSet& key_parameters,
+ keystore::AuthorizationSet* hardware_enforced_characteristics,
+ keystore::AuthorizationSet* software_enforced_characteristics) = 0;
// Provides the [hardware|software]_enforced_characteristics of a key
// identified by |key_name|. Returns KM_ERROR_OK on success and a Keystore
@@ -112,17 +111,17 @@
// [hardware|software]_enforced_characteristics of the key are provided on
// success. Returns KM_ERROR_OK on success and a Keystore ResponseCode or
// keymaster_error_t on failure.
- virtual KeyStoreNativeReturnCode importKey(const std::string& key_name,
- const keystore::AuthorizationSet& key_parameters,
- KeyFormat key_format, const std::string& key_data,
- keystore::AuthorizationSet* hardware_enforced_characteristics,
- keystore::AuthorizationSet* software_enforced_characteristics) = 0;
+ virtual KeyStoreNativeReturnCode
+ importKey(const std::string& key_name, const keystore::AuthorizationSet& key_parameters,
+ KeyFormat key_format, const std::string& key_data,
+ keystore::AuthorizationSet* hardware_enforced_characteristics,
+ keystore::AuthorizationSet* software_enforced_characteristics) = 0;
// Exports the public key identified by |key_name| to |export_data| using
// |export_format|. Returns KM_ERROR_OK on success and a Keystore ResponseCode
// or keymaster_error_t on failure.
virtual KeyStoreNativeReturnCode exportKey(KeyFormat export_format, const std::string& key_name,
- std::string* export_data) = 0;
+ std::string* export_data) = 0;
// Deletes the key identified by |key_name|. Returns KM_ERROR_OK on success
// and a Keystore ResponseCode or keymaster_error_t on failure.
@@ -137,32 +136,30 @@
// |input_parameters|. On success, any |output_parameters| and an operation
// |handle| are populated. Returns KM_ERROR_OK on success and a Keystore
// ResponseCode or keymaster_error_t on failure.
- virtual KeyStoreNativeReturnCode beginOperation(KeyPurpose purpose, const std::string& key_name,
- const keystore::AuthorizationSet& input_parameters,
- keystore::AuthorizationSet* output_parameters,
- uint64_t* handle) = 0;
+ virtual KeyStoreNativeReturnCode
+ beginOperation(KeyPurpose purpose, const std::string& key_name,
+ const keystore::AuthorizationSet& input_parameters,
+ keystore::AuthorizationSet* output_parameters, uint64_t* handle) = 0;
// Continues the operation associated with |handle| using the given
// |input_parameters| and |input_data|. On success, the
// |num_input_bytes_consumed| and any |output_parameters| are populated. Any
// |output_data| will be appended. Returns KM_ERROR_OK on success and a
// Keystore ResponseCode or keymaster_error_t on failure.
- virtual KeyStoreNativeReturnCode updateOperation(uint64_t handle,
- const keystore::AuthorizationSet& input_parameters,
- const std::string& input_data, size_t* num_input_bytes_consumed,
- keystore::AuthorizationSet* output_parameters,
- std::string* output_data) = 0;
+ virtual KeyStoreNativeReturnCode
+ updateOperation(uint64_t handle, const keystore::AuthorizationSet& input_parameters,
+ const std::string& input_data, size_t* num_input_bytes_consumed,
+ keystore::AuthorizationSet* output_parameters, std::string* output_data) = 0;
// Finishes the operation associated with |handle| using the given
// |input_parameters| and, if necessary, a |signature_to_verify|. On success,
// any |output_parameters| are populated and |output_data| is appended.
// Returns KM_ERROR_OK on success and a Keystore ResponseCode or
// keymaster_error_t on failure.
- virtual KeyStoreNativeReturnCode finishOperation(uint64_t handle,
- const keystore::AuthorizationSet& input_parameters,
- const std::string& signature_to_verify,
- keystore::AuthorizationSet* output_parameters,
- std::string* output_data) = 0;
+ virtual KeyStoreNativeReturnCode
+ finishOperation(uint64_t handle, const keystore::AuthorizationSet& input_parameters,
+ const std::string& signature_to_verify,
+ keystore::AuthorizationSet* output_parameters, std::string* output_data) = 0;
// Aborts the operation associated with |handle|. Returns KM_ERROR_OK on
// success and a Keystore ResponseCode or keymaster_error_t on failure.
diff --git a/keystore/include/keystore/keystore_client_impl.h b/keystore/include/keystore/keystore_client_impl.h
index eb02275..a11e2fe 100644
--- a/keystore/include/keystore/keystore_client_impl.h
+++ b/keystore/include/keystore/keystore_client_impl.h
@@ -17,13 +17,13 @@
#include "keystore_client.h"
-#include <string>
#include <map>
+#include <string>
#include <vector>
+#include <android/security/IKeystoreService.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
-#include "IKeystoreService.h"
#include <utils/StrongPointer.h>
namespace keystore {
@@ -44,37 +44,38 @@
keystore::AuthorizationSet* output_parameters,
std::string* output_data) override;
KeyStoreNativeReturnCode addRandomNumberGeneratorEntropy(const std::string& entropy) override;
- KeyStoreNativeReturnCode generateKey(const std::string& key_name,
- const keystore::AuthorizationSet& key_parameters,
- keystore::AuthorizationSet* hardware_enforced_characteristics,
- keystore::AuthorizationSet* software_enforced_characteristics) override;
+ KeyStoreNativeReturnCode
+ generateKey(const std::string& key_name, const keystore::AuthorizationSet& key_parameters,
+ keystore::AuthorizationSet* hardware_enforced_characteristics,
+ keystore::AuthorizationSet* software_enforced_characteristics) override;
KeyStoreNativeReturnCode
getKeyCharacteristics(const std::string& key_name,
keystore::AuthorizationSet* hardware_enforced_characteristics,
keystore::AuthorizationSet* software_enforced_characteristics) override;
- KeyStoreNativeReturnCode importKey(const std::string& key_name,
- const keystore::AuthorizationSet& key_parameters,
- KeyFormat key_format, const std::string& key_data,
- keystore::AuthorizationSet* hardware_enforced_characteristics,
- keystore::AuthorizationSet* software_enforced_characteristics) override;
+ KeyStoreNativeReturnCode
+ importKey(const std::string& key_name, const keystore::AuthorizationSet& key_parameters,
+ KeyFormat key_format, const std::string& key_data,
+ keystore::AuthorizationSet* hardware_enforced_characteristics,
+ keystore::AuthorizationSet* software_enforced_characteristics) override;
KeyStoreNativeReturnCode exportKey(KeyFormat export_format, const std::string& key_name,
- std::string* export_data) override;
+ std::string* export_data) override;
KeyStoreNativeReturnCode deleteKey(const std::string& key_name) override;
KeyStoreNativeReturnCode deleteAllKeys() override;
KeyStoreNativeReturnCode beginOperation(KeyPurpose purpose, const std::string& key_name,
- const keystore::AuthorizationSet& input_parameters,
- keystore::AuthorizationSet* output_parameters,
- uint64_t* handle) override;
+ const keystore::AuthorizationSet& input_parameters,
+ keystore::AuthorizationSet* output_parameters,
+ uint64_t* handle) override;
KeyStoreNativeReturnCode updateOperation(uint64_t handle,
- const keystore::AuthorizationSet& input_parameters,
- const std::string& input_data, size_t* num_input_bytes_consumed,
- keystore::AuthorizationSet* output_parameters,
- std::string* output_data) override;
+ const keystore::AuthorizationSet& input_parameters,
+ const std::string& input_data,
+ size_t* num_input_bytes_consumed,
+ keystore::AuthorizationSet* output_parameters,
+ std::string* output_data) override;
KeyStoreNativeReturnCode finishOperation(uint64_t handle,
- const keystore::AuthorizationSet& input_parameters,
- const std::string& signature_to_verify,
- keystore::AuthorizationSet* output_parameters,
- std::string* output_data) override;
+ const keystore::AuthorizationSet& input_parameters,
+ const std::string& signature_to_verify,
+ keystore::AuthorizationSet* output_parameters,
+ std::string* output_data) override;
KeyStoreNativeReturnCode abortOperation(uint64_t handle) override;
bool doesKeyExist(const std::string& key_name) override;
bool listKeys(const std::string& prefix, std::vector<std::string>* key_name_list) override;
@@ -85,7 +86,7 @@
// Maps a keystore error code to a code where all success cases use
// KM_ERROR_OK (not keystore's NO_ERROR).
-// int32_t mapKeystoreError(int32_t keystore_error);
+ // int32_t mapKeystoreError(int32_t keystore_error);
// Creates an encryption key suitable for EncryptWithAuthentication or
// verifies attributes if the key already exists. Returns true on success.
@@ -107,7 +108,7 @@
android::sp<android::IServiceManager> service_manager_;
android::sp<android::IBinder> keystore_binder_;
- android::sp<android::IKeystoreService> keystore_;
+ android::sp<android::security::IKeystoreService> keystore_;
uint64_t next_virtual_handle_ = 1;
std::map<uint64_t, android::sp<android::IBinder>> active_operations_;
diff --git a/keystore/include/keystore/keystore_client_mock.h b/keystore/include/keystore/keystore_client_mock.h
index 2d1f499..b16367f 100644
--- a/keystore/include/keystore/keystore_client_mock.h
+++ b/keystore/include/keystore/keystore_client_mock.h
@@ -15,8 +15,8 @@
#ifndef KEYSTORE_KEYSTORE_CLIENT_MOCK_H_
#define KEYSTORE_KEYSTORE_CLIENT_MOCK_H_
-#include "gmock/gmock.h"
#include "keystore/keystore_client.h"
+#include "gmock/gmock.h"
using testing::_;
diff --git a/keystore/include/keystore/keystore_get.h b/keystore/include/keystore/keystore_get.h
index 4bddd70..4c3d838 100644
--- a/keystore/include/keystore/keystore_get.h
+++ b/keystore/include/keystore/keystore_get.h
@@ -30,7 +30,7 @@
* length. The third argument is a pointer to an array that will be malloc()
* and the caller is responsible for calling free() on the buffer.
*/
-ssize_t keystore_get(const char *key, size_t length, uint8_t** value);
+ssize_t keystore_get(const char* key, size_t length, uint8_t** value);
#ifdef __cplusplus
}
diff --git a/keystore/include/keystore/keystore_hidl_support.h b/keystore/include/keystore/keystore_hidl_support.h
index 3c64d2a..0edaa3b 100644
--- a/keystore/include/keystore/keystore_hidl_support.h
+++ b/keystore/include/keystore/keystore_hidl_support.h
@@ -19,6 +19,7 @@
#define KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hardware/hw_auth_token.h>
#include <hidl/Status.h>
#include <keystore/keymaster_tags.h>
#include <ostream>
@@ -121,6 +122,38 @@
return result;
}
+template <typename T, typename InIter>
+inline static InIter copy_bytes_from_iterator(T* value, InIter src) {
+ uint8_t* value_ptr = reinterpret_cast<uint8_t*>(value);
+ std::copy(src, src + sizeof(T), value_ptr);
+ return src + sizeof(T);
+}
+
+inline static HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) {
+ HardwareAuthToken token;
+ static_assert(
+ std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value,
+ "This function assumes token HMAC is 32 bytes, but it might not be.");
+ static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
+ sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
+ sizeof(token.timestamp) + 32 /* HMAC size */
+ == sizeof(hw_auth_token_t),
+ "HardwareAuthToken content size does not match hw_auth_token_t size");
+
+ if (buffer.size() != sizeof(hw_auth_token_t)) return {};
+
+ auto pos = buffer.begin();
+ ++pos; // skip first byte
+ pos = copy_bytes_from_iterator(&token.challenge, pos);
+ pos = copy_bytes_from_iterator(&token.userId, pos);
+ pos = copy_bytes_from_iterator(&token.authenticatorId, pos);
+ pos = copy_bytes_from_iterator(&token.authenticatorType, pos);
+ pos = copy_bytes_from_iterator(&token.timestamp, pos);
+ pos = std::copy(pos, pos + token.hmac.size(), &token.hmac[0]);
+
+ return token;
+}
+
inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) {
return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
}
diff --git a/keystore/include/keystore/keystore_return_types.h b/keystore/include/keystore/keystore_return_types.h
index 70380c3..52d700a 100644
--- a/keystore/include/keystore/keystore_return_types.h
+++ b/keystore/include/keystore/keystore_return_types.h
@@ -46,6 +46,7 @@
KeyStoreServiceReturnCode(const KeyStoreServiceReturnCode& errorCode)
: errorCode_(errorCode.errorCode_) {}
KeyStoreServiceReturnCode(const KeyStoreNativeReturnCode& errorCode);
+ explicit inline KeyStoreServiceReturnCode(const int32_t& errorCode) : errorCode_(errorCode) {}
inline KeyStoreServiceReturnCode& operator=(const ErrorCode& errorCode) {
errorCode_ = int32_t(errorCode);
return *this;
@@ -62,8 +63,9 @@
return errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) ||
errorCode_ == static_cast<int32_t>(ErrorCode::OK);
}
+
inline operator int32_t() const {
- if (!errorCode_) return static_cast<int32_t>(ResponseCode::NO_ERROR);
+ if (!errorCode_) return static_cast<int32_t>(ResponseCode::NO_ERROR /* 1 */);
return errorCode_;
}
inline bool operator==(const ResponseCode& rhs) const {
@@ -117,6 +119,7 @@
KeyStoreNativeReturnCode(const ResponseCode& errorCode) : errorCode_(int32_t(errorCode)) {}
KeyStoreNativeReturnCode(const KeyStoreNativeReturnCode& errorCode)
: errorCode_(errorCode.errorCode_) {}
+ explicit inline KeyStoreNativeReturnCode(const int32_t& errorCode) : errorCode_(errorCode) {}
KeyStoreNativeReturnCode(const KeyStoreServiceReturnCode& errorcode);
inline KeyStoreNativeReturnCode& operator=(const ErrorCode& errorCode) {
errorCode_ = int32_t(errorCode);
@@ -135,8 +138,8 @@
errorCode_ == static_cast<int32_t>(ErrorCode::OK);
}
inline operator int32_t() const {
- if (errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR)) {
- return static_cast<int32_t>(ErrorCode::OK);
+ if (errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) /* 1 */) {
+ return static_cast<int32_t>(ErrorCode::OK) /* 0 */;
}
return errorCode_;
}
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index f6786b8..b309ad6 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "keystore"
#include "key_store_service.h"
+#include "include/keystore/KeystoreArg.h"
#include <fcntl.h>
#include <sys/stat.h>
@@ -39,12 +40,23 @@
#include "keystore_utils.h"
#include <keystore/keystore_hidl_support.h>
+#include <hardware/hw_auth_token.h>
+
namespace keystore {
using namespace android;
namespace {
+using ::android::binder::Status;
+using ::android::hardware::keymaster::V3_0::KeyFormat;
+using android::security::KeystoreArg;
+using android::security::keymaster::ExportResult;
+using android::security::keymaster::KeymasterArguments;
+using android::security::keymaster::KeymasterBlob;
+using android::security::keymaster::KeymasterCertificateChain;
+using android::security::keymaster::OperationResult;
+
constexpr size_t kMaxOperations = 15;
constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
const char* kTimestampFilePath = "timestamp";
@@ -124,55 +136,52 @@
void KeyStoreService::binderDied(const wp<IBinder>& who) {
auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
for (const auto& token : operations) {
- abort(token);
+ int32_t unused_result;
+ abort(token, &unused_result);
}
}
-KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
+Status KeyStoreService::getState(int32_t userId, int32_t* aidl_return) {
if (!checkBinderPermission(P_GET_STATE)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
-
- return ResponseCode(mKeyStore->getState(userId));
+ *aidl_return = mKeyStore->getState(userId);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::get(const String16& name, int32_t uid,
- hidl_vec<uint8_t>* item) {
+Status KeyStoreService::get(const String16& name, int32_t uid, ::std::vector<uint8_t>* item) {
uid_t targetUid = getEffectiveUid(uid);
if (!checkBinderPermission(P_GET, targetUid)) {
- return ResponseCode::PERMISSION_DENIED;
+ // see keystore/keystore.h
+ return Status::fromServiceSpecificError(
+ static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
}
String8 name8(name);
Blob keyBlob;
-
KeyStoreServiceReturnCode rc =
mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_GENERIC);
if (!rc.isOk()) {
- if (item) *item = hidl_vec<uint8_t>();
- return rc;
+ *item = ::std::vector<uint8_t>();
+ // Return empty array if key is not found
+ // TODO: consider having returned value nullable or parse exception on the client.
+ return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
}
-
- // Do not replace this with "if (item) *item = blob2hidlVec(keyBlob)"!
- // blob2hidlVec creates a hidl_vec<uint8_t> that references, but not owns, the data in keyBlob
- // the subsequent assignment (*item = resultBlob) makes a deep copy, so that *item will own the
- // corresponding resources.
auto resultBlob = blob2hidlVec(keyBlob);
- if (item) {
- *item = resultBlob;
- }
-
- return ResponseCode::NO_ERROR;
+ // The static_cast here is needed to prevent a move, forcing a deep copy.
+ if (item) *item = static_cast<const hidl_vec<uint8_t>&>(blob2hidlVec(keyBlob));
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::insert(const String16& name,
- const hidl_vec<uint8_t>& item, int targetUid,
- int32_t flags) {
+Status KeyStoreService::insert(const String16& name, const ::std::vector<uint8_t>& item,
+ int targetUid, int32_t flags, int32_t* aidl_return) {
targetUid = getEffectiveUid(targetUid);
- auto result =
+ KeyStoreServiceReturnCode result =
checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!result.isOk()) {
- return result;
+ *aidl_return = static_cast<int32_t>(result);
+ return Status::ok();
}
String8 name8(name);
@@ -181,72 +190,93 @@
Blob keyBlob(&item[0], item.size(), NULL, 0, ::TYPE_GENERIC);
keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
- return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid));
+ *aidl_return =
+ static_cast<int32_t>(mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid)));
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::del(const String16& name, int targetUid) {
+Status KeyStoreService::del(const String16& name, int targetUid, int32_t* aidl_return) {
targetUid = getEffectiveUid(targetUid);
if (!checkBinderPermission(P_DELETE, targetUid)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
String8 name8(name);
ALOGI("del %s %d", name8.string(), targetUid);
auto filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_ANY);
- if (!filename.isOk()) return ResponseCode::KEY_NOT_FOUND;
+ if (!filename.isOk()) {
+ *aidl_return = static_cast<int32_t>(ResponseCode::KEY_NOT_FOUND);
+ return Status::ok();
+ }
- ResponseCode result = mKeyStore->del(filename.value().string(), ::TYPE_ANY,
- get_user_id(targetUid));
+ ResponseCode result =
+ mKeyStore->del(filename.value().string(), ::TYPE_ANY, get_user_id(targetUid));
if (result != ResponseCode::NO_ERROR) {
- return result;
+ *aidl_return = static_cast<int32_t>(result);
+ return Status::ok();
}
filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS);
if (filename.isOk()) {
- return mKeyStore->del(filename.value().string(), ::TYPE_KEY_CHARACTERISTICS,
- get_user_id(targetUid));
+ *aidl_return = static_cast<int32_t>(mKeyStore->del(
+ filename.value().string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid)));
+ return Status::ok();
}
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::exist(const String16& name, int targetUid) {
+Status KeyStoreService::exist(const String16& name, int targetUid, int32_t* aidl_return) {
targetUid = getEffectiveUid(targetUid);
if (!checkBinderPermission(P_EXIST, targetUid)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
- return filename.isOk() ? ResponseCode::NO_ERROR : ResponseCode::KEY_NOT_FOUND;
+ *aidl_return = static_cast<int32_t>(filename.isOk() ? ResponseCode::NO_ERROR
+ : ResponseCode::KEY_NOT_FOUND);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::list(const String16& prefix, int targetUid,
- Vector<String16>* matches) {
+Status KeyStoreService::list(const String16& prefix, int targetUid,
+ ::std::vector<::android::String16>* matches) {
targetUid = getEffectiveUid(targetUid);
if (!checkBinderPermission(P_LIST, targetUid)) {
- return ResponseCode::PERMISSION_DENIED;
+ return Status::fromServiceSpecificError(
+ static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
}
const String8 prefix8(prefix);
String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
-
- if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
- return ResponseCode::SYSTEM_ERROR;
+ android::Vector<android::String16> matches_internal;
+ if (mKeyStore->list(filename, &matches_internal, get_user_id(targetUid)) !=
+ ResponseCode::NO_ERROR) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
}
- return ResponseCode::NO_ERROR;
+ matches->clear();
+ for (size_t i = 0; i < matches_internal.size(); ++i) {
+ matches->push_back(matches_internal[i]);
+ }
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::reset() {
+Status KeyStoreService::reset(int32_t* aidl_return) {
if (!checkBinderPermission(P_RESET)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
mKeyStore->resetUser(get_user_id(callingUid), false);
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::onUserPasswordChanged(int32_t userId,
- const String16& password) {
+Status KeyStoreService::onUserPasswordChanged(int32_t userId, const String16& password,
+ int32_t* aidl_return) {
if (!checkBinderPermission(P_PASSWORD)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
const String8 password8(password);
@@ -257,31 +287,37 @@
if (password.size() == 0) {
ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
mKeyStore->resetUser(userId, true);
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
} else {
switch (mKeyStore->getState(userId)) {
case ::STATE_UNINITIALIZED: {
// generate master key, encrypt with password, write to file,
// initialize mMasterKey*.
- return mKeyStore->initializeUser(password8, userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
+ return Status::ok();
}
case ::STATE_NO_ERROR: {
// rewrite master key with new password.
- return mKeyStore->writeMasterKey(password8, userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->writeMasterKey(password8, userId));
+ return Status::ok();
}
case ::STATE_LOCKED: {
ALOGE("Changing user %d's password while locked, clearing old encryption", userId);
mKeyStore->resetUser(userId, true);
- return mKeyStore->initializeUser(password8, userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
+ return Status::ok();
}
}
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
}
-KeyStoreServiceReturnCode KeyStoreService::onUserAdded(int32_t userId, int32_t parentId) {
+Status KeyStoreService::onUserAdded(int32_t userId, int32_t parentId, int32_t* aidl_return) {
if (!checkBinderPermission(P_USER_CHANGED)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
// Sanity check that the new user has an empty keystore.
@@ -295,39 +331,47 @@
// password of the parent profile is not known here, the best we can do is copy the parent's
// master key and master key file. This makes this profile use the same master key as the
// parent profile, forever.
- return mKeyStore->copyMasterKey(parentId, userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->copyMasterKey(parentId, userId));
+ return Status::ok();
} else {
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
}
-KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
+Status KeyStoreService::onUserRemoved(int32_t userId, int32_t* aidl_return) {
if (!checkBinderPermission(P_USER_CHANGED)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
mKeyStore->resetUser(userId, false);
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
+Status KeyStoreService::lock(int32_t userId, int32_t* aidl_return) {
if (!checkBinderPermission(P_LOCK)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
State state = mKeyStore->getState(userId);
if (state != ::STATE_NO_ERROR) {
ALOGD("calling lock in state: %d", state);
- return ResponseCode(state);
+ *aidl_return = static_cast<int32_t>(ResponseCode(state));
+ return Status::ok();
}
mKeyStore->lock(userId);
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16& pw) {
+Status KeyStoreService::unlock(int32_t userId, const String16& pw, int32_t* aidl_return) {
if (!checkBinderPermission(P_UNLOCK)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
State state = mKeyStore->getState(userId);
@@ -343,30 +387,37 @@
ALOGE("unlock called on keystore in unknown state: %d", state);
break;
}
- return ResponseCode(state);
+ *aidl_return = static_cast<int32_t>(ResponseCode(state));
+ return Status::ok();
}
const String8 password8(pw);
// read master key, decrypt with password, initialize mMasterKey*.
- return mKeyStore->readMasterKey(password8, userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->readMasterKey(password8, userId));
+ return Status::ok();
}
-bool KeyStoreService::isEmpty(int32_t userId) {
+Status KeyStoreService::isEmpty(int32_t userId, int32_t* aidl_return) {
if (!checkBinderPermission(P_IS_EMPTY)) {
- return false;
+ *aidl_return = static_cast<int32_t>(false);
+ return Status::ok();
}
- return mKeyStore->isEmpty(userId);
+ *aidl_return = static_cast<int32_t>(mKeyStore->isEmpty(userId));
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::generate(const String16& name, int32_t targetUid,
- int32_t keyType, int32_t keySize, int32_t flags,
- Vector<sp<KeystoreArg>>* args) {
+Status KeyStoreService::generate(const String16& name, int32_t targetUid, int32_t keyType,
+ int32_t keySize, int32_t flags,
+ const ::android::security::KeystoreArguments& keystoreArgs,
+ int32_t* aidl_return) {
+ const Vector<sp<KeystoreArg>>* args = &(keystoreArgs.getArguments());
targetUid = getEffectiveUid(targetUid);
- auto result =
+ KeyStoreServiceReturnCode result =
checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!result.isOk()) {
- return result;
+ *aidl_return = static_cast<int32_t>(result);
+ return Status::ok();
}
keystore::AuthorizationSet params;
@@ -379,7 +430,8 @@
keySize = EC_DEFAULT_KEY_SIZE;
} else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
ALOGI("invalid key size %d", keySize);
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
params.push_back(TAG_KEY_SIZE, keySize);
break;
@@ -390,13 +442,15 @@
keySize = RSA_DEFAULT_KEY_SIZE;
} else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
ALOGI("invalid key size %d", keySize);
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
params.push_back(TAG_KEY_SIZE, keySize);
unsigned long exponent = RSA_DEFAULT_EXPONENT;
if (args->size() > 1) {
ALOGI("invalid number of arguments: %zu", args->size());
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
} else if (args->size() == 1) {
const sp<KeystoreArg>& expArg = args->itemAt(0);
if (expArg != NULL) {
@@ -404,16 +458,19 @@
reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), NULL));
if (pubExpBn.get() == NULL) {
ALOGI("Could not convert public exponent to BN");
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
exponent = BN_get_word(pubExpBn.get());
if (exponent == 0xFFFFFFFFL) {
ALOGW("cannot represent public exponent as a long value");
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
} else {
ALOGW("public exponent not read");
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
}
params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
@@ -421,31 +478,36 @@
}
default: {
ALOGW("Unsupported key type %d", keyType);
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
}
- auto rc = generateKey(name, params.hidl_data(), hidl_vec<uint8_t>(), targetUid, flags,
- /*outCharacteristics*/ NULL);
- if (!rc.isOk()) {
- ALOGW("generate failed: %d", int32_t(rc));
+ int32_t aidl_result;
+ android::security::keymaster::KeyCharacteristics unused_characteristics;
+ auto rc = generateKey(name, KeymasterArguments(params.hidl_data()), ::std::vector<uint8_t>(),
+ targetUid, flags, &unused_characteristics, &aidl_result);
+ if (!KeyStoreServiceReturnCode(aidl_result).isOk()) {
+ ALOGW("generate failed: %d", int32_t(aidl_result));
}
- return translateResultToLegacyResult(rc);
+ *aidl_return = aidl_result;
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::import(const String16& name,
- const hidl_vec<uint8_t>& data, int targetUid,
- int32_t flags) {
+Status KeyStoreService::import_key(const String16& name, const ::std::vector<uint8_t>& data,
+ int targetUid, int32_t flags, int32_t* aidl_return) {
const uint8_t* ptr = &data[0];
Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
if (!pkcs8.get()) {
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
if (!pkey.get()) {
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
int type = EVP_PKEY_type(pkey->type);
AuthorizationSet params;
@@ -459,33 +521,44 @@
break;
default:
ALOGW("Unsupported key type %d", type);
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
- auto rc = importKey(name, params.hidl_data(), KeyFormat::PKCS8, data, targetUid, flags,
- /*outCharacteristics*/ NULL);
+ int import_result;
+ auto rc = importKey(name, KeymasterArguments(params.hidl_data()),
+ static_cast<int32_t>(KeyFormat::PKCS8), data, targetUid, flags,
+ /*outCharacteristics*/ NULL, &import_result);
- if (!rc.isOk()) {
- ALOGW("importKey failed: %d", int32_t(rc));
+ if (!KeyStoreServiceReturnCode(import_result).isOk()) {
+ ALOGW("importKey failed: %d", int32_t(import_result));
}
- return translateResultToLegacyResult(rc);
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::sign(const String16& name, const hidl_vec<uint8_t>& data,
- hidl_vec<uint8_t>* out) {
+Status KeyStoreService::sign(const String16& name, const ::std::vector<uint8_t>& data,
+ ::std::vector<uint8_t>* out) {
if (!checkBinderPermission(P_SIGN)) {
- return ResponseCode::PERMISSION_DENIED;
+ return Status::fromServiceSpecificError(
+ static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
}
- return doLegacySignVerify(name, data, out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
+ hidl_vec<uint8_t> legacy_out;
+ KeyStoreServiceReturnCode res =
+ doLegacySignVerify(name, data, &legacy_out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
+ *out = legacy_out;
+ return Status::fromServiceSpecificError((res));
}
-KeyStoreServiceReturnCode KeyStoreService::verify(const String16& name,
- const hidl_vec<uint8_t>& data,
- const hidl_vec<uint8_t>& signature) {
+Status KeyStoreService::verify(const String16& name, const ::std::vector<uint8_t>& data,
+ const ::std::vector<uint8_t>& signature, int32_t* aidl_return) {
if (!checkBinderPermission(P_VERIFY)) {
- return ResponseCode::PERMISSION_DENIED;
+ return Status::fromServiceSpecificError(
+ static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
}
- return doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY);
+ *aidl_return = static_cast<int32_t>(
+ doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY));
+ return Status::ok();
}
/*
@@ -499,72 +572,86 @@
* "del_key" since the Java code doesn't really communicate what it's
* intentions are.
*/
-KeyStoreServiceReturnCode KeyStoreService::get_pubkey(const String16& name,
- hidl_vec<uint8_t>* pubKey) {
- ExportResult result;
- exportKey(name, KeyFormat::X509, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF, &result);
+Status KeyStoreService::get_pubkey(const String16& name, ::std::vector<uint8_t>* pubKey) {
+ android::security::keymaster::ExportResult result;
+ KeymasterBlob clientId;
+ KeymasterBlob appId;
+ exportKey(name, static_cast<int32_t>(KeyFormat::X509), clientId, appId, UID_SELF, &result);
if (!result.resultCode.isOk()) {
ALOGW("export failed: %d", int32_t(result.resultCode));
- return translateResultToLegacyResult(result.resultCode);
+ return Status::fromServiceSpecificError(static_cast<int32_t>(result.resultCode));
}
if (pubKey) *pubKey = std::move(result.exportData);
- return ResponseCode::NO_ERROR;
+ return Status::ok();
}
-String16 KeyStoreService::grant(const String16& name, int32_t granteeUid) {
+Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
+ ::android::String16* aidl_return) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
if (!result.isOk()) {
- return String16();
+ *aidl_return = String16();
+ return Status::ok();
}
String8 name8(name);
String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
- return String16();
+ *aidl_return = String16();
+ return Status::ok();
}
- return String16(mKeyStore->addGrant(String8(name).string(), callingUid, granteeUid).c_str());
+ *aidl_return =
+ String16(mKeyStore->addGrant(String8(name).string(), callingUid, granteeUid).c_str());
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
+Status KeyStoreService::ungrant(const String16& name, int32_t granteeUid, int32_t* aidl_return) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
- auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
+ KeyStoreServiceReturnCode result = checkBinderPermissionAndKeystoreState(P_GRANT);
if (!result.isOk()) {
- return result;
+ *aidl_return = static_cast<int32_t>(result);
+ return Status::ok();
}
String8 name8(name);
String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
- return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
+ *aidl_return = static_cast<int32_t>((errno != ENOENT) ? ResponseCode::SYSTEM_ERROR
+ : ResponseCode::KEY_NOT_FOUND);
+ return Status::ok();
}
- return mKeyStore->removeGrant(name8, callingUid, granteeUid) ? ResponseCode::NO_ERROR
- : ResponseCode::KEY_NOT_FOUND;
+ *aidl_return = static_cast<int32_t>(mKeyStore->removeGrant(name8, callingUid, granteeUid)
+ ? ResponseCode::NO_ERROR
+ : ResponseCode::KEY_NOT_FOUND);
+ return Status::ok();
}
-int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
+Status KeyStoreService::getmtime(const String16& name, int32_t uid, int64_t* time) {
uid_t targetUid = getEffectiveUid(uid);
if (!checkBinderPermission(P_GET, targetUid)) {
ALOGW("permission denied for %d: getmtime", targetUid);
- return -1L;
+ *time = -1L;
+ return Status::ok();
}
auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
if (!filename.isOk()) {
ALOGW("could not access %s for getmtime", filename.value().string());
- return -1L;
+ *time = -1L;
+ return Status::ok();
}
int fd = TEMP_FAILURE_RETRY(open(filename.value().string(), O_NOFOLLOW, O_RDONLY));
if (fd < 0) {
ALOGW("could not open %s for getmtime", filename.value().string());
- return -1L;
+ *time = -1L;
+ return Status::ok();
}
struct stat s;
@@ -572,33 +659,38 @@
close(fd);
if (ret == -1) {
ALOGW("could not stat %s for getmtime", filename.value().string());
- return -1L;
+ *time = -1L;
+ return Status::ok();
}
- return static_cast<int64_t>(s.st_mtime);
+ *time = static_cast<int64_t>(s.st_mtime);
+ return Status::ok();
}
// TODO(tuckeris): This is dead code, remove it. Don't bother copying over key characteristics here
-KeyStoreServiceReturnCode KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid,
- const String16& destKey, int32_t destUid) {
+Status KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
+ int32_t destUid, int32_t* aidl_return) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
pid_t spid = IPCThreadState::self()->getCallingPid();
if (!has_permission(callingUid, P_DUPLICATE, spid)) {
ALOGW("permission denied for %d: duplicate", callingUid);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
State state = mKeyStore->getState(get_user_id(callingUid));
if (!isKeystoreUnlocked(state)) {
ALOGD("calling duplicate in state: %d", state);
- return ResponseCode(state);
+ *aidl_return = static_cast<int32_t>(ResponseCode(state));
+ return Status::ok();
}
if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
srcUid = callingUid;
} else if (!is_granted_to(callingUid, srcUid)) {
ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
if (destUid == -1) {
@@ -610,12 +702,14 @@
ALOGD("can only duplicate from caller to other or to same uid: "
"calling=%d, srcUid=%d, destUid=%d",
callingUid, srcUid, destUid);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
if (!is_granted_to(callingUid, destUid)) {
ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
}
@@ -627,27 +721,33 @@
if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
ALOGD("destination already exists: %s", targetFile.string());
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
Blob keyBlob;
ResponseCode responseCode =
mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, get_user_id(srcUid));
if (responseCode != ResponseCode::NO_ERROR) {
- return responseCode;
+ *aidl_return = static_cast<int32_t>(responseCode);
+ return Status::ok();
}
- return mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid));
+ *aidl_return =
+ static_cast<int32_t>(mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid)));
+ return Status::ok();
}
-int32_t KeyStoreService::is_hardware_backed(const String16& keyType) {
- return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
+Status KeyStoreService::is_hardware_backed(const String16& keyType, int32_t* aidl_return) {
+ *aidl_return = static_cast<int32_t>(mKeyStore->isHardwareBacked(keyType) ? 1 : 0);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::clear_uid(int64_t targetUid64) {
+Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* aidl_return) {
uid_t targetUid = getEffectiveUid(targetUid64);
if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
ALOGI("clear_uid %" PRId64, targetUid64);
@@ -656,7 +756,8 @@
String8 prefix = String8::format("%u_", targetUid);
Vector<String16> aliases;
if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
for (uint32_t i = 0; i < aliases.size(); i++) {
@@ -680,56 +781,68 @@
mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
}
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::addRngEntropy(const hidl_vec<uint8_t>& entropy) {
+Status KeyStoreService::addRngEntropy(const ::std::vector<uint8_t>& entropy, int32_t* aidl_return) {
const auto& device = mKeyStore->getDevice();
- return KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy));
+ *aidl_return = static_cast<int32_t>(
+ KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy))));
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::generateKey(const String16& name,
- const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int uid,
- int flags,
- KeyCharacteristics* outCharacteristics) {
+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) {
// TODO(jbires): remove this getCallingUid call upon implementation of b/25646100
uid_t originalUid = IPCThreadState::self()->getCallingUid();
uid = getEffectiveUid(uid);
KeyStoreServiceReturnCode rc =
checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
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);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
- if (containsTag(params, Tag::INCLUDE_UNIQUE_ID)) {
+
+ 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()) {
- return ResponseCode::PERMISSION_DENIED;
+ originalUid != IPCThreadState::self()->getCallingUid()) {
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
}
bool usingFallback = false;
auto& dev = mKeyStore->getDevice();
- AuthorizationSet keyCharacteristics = params;
+ AuthorizationSet keyCharacteristics = params.getParameters();
// TODO: Seed from Linux RNG before this.
- rc = addRngEntropy(entropy);
- if (!rc.isOk()) {
- return rc;
+ int32_t result;
+ addRngEntropy(entropy, &result); // binder error is not possible.
+ if (!KeyStoreServiceReturnCode(result).isOk()) {
+ *aidl_return = static_cast<int32_t>(result);
+ return Status::ok();
}
KeyStoreServiceReturnCode error;
- auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+ auto hidl_cb = [&](ErrorCode ret, const ::std::vector<uint8_t>& hidlKeyBlob,
const KeyCharacteristics& keyCharacteristics) {
error = ret;
if (!error.isOk()) {
return;
}
- if (outCharacteristics) *outCharacteristics = keyCharacteristics;
+ if (outCharacteristics)
+ *outCharacteristics =
+ ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
// Write the key
String8 name8(name);
@@ -738,7 +851,8 @@
Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
keyBlob.setFallback(usingFallback);
keyBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
- if (isAuthenticationBound(params) && !keyBlob.isCriticalToDeviceEncryption()) {
+ if (isAuthenticationBound(params.getParameters()) &&
+ !keyBlob.isCriticalToDeviceEncryption()) {
keyBlob.setSuperEncrypted(true);
}
keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -746,23 +860,27 @@
error = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
};
- rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(params, hidl_cb));
+ rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(params.getParameters(), hidl_cb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
if (!error.isOk()) {
ALOGE("Failed to generate key -> falling back to software keymaster");
usingFallback = true;
auto fallback = mKeyStore->getFallbackDevice();
if (!fallback.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
- rc = KS_HANDLE_HIDL_ERROR(fallback.value()->generateKey(params, hidl_cb));
+ rc = KS_HANDLE_HIDL_ERROR(fallback.value()->generateKey(params.getParameters(), hidl_cb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
if (!error.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
}
@@ -773,7 +891,8 @@
std::stringstream kc_stream;
keyCharacteristics.Serialize(&kc_stream);
if (kc_stream.bad()) {
- return ResponseCode::SYSTEM_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
}
auto kc_buf = kc_stream.str();
Blob charBlob(reinterpret_cast<const uint8_t*>(kc_buf.data()), kc_buf.size(), NULL, 0,
@@ -781,15 +900,19 @@
charBlob.setFallback(usingFallback);
charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
- return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
+ *aidl_return =
+ static_cast<int32_t>(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid)));
+ return Status::ok();
}
-KeyStoreServiceReturnCode
-KeyStoreService::getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
- const hidl_vec<uint8_t>& appData, int32_t uid,
- KeyCharacteristics* outCharacteristics) {
+Status KeyStoreService::getKeyCharacteristics(
+ const String16& name, const ::android::security::keymaster::KeymasterBlob& clientId,
+ const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
+ ::android::security::keymaster::KeyCharacteristics* outCharacteristics, int32_t* aidl_return) {
if (!outCharacteristics) {
- return ErrorCode::UNEXPECTED_NULL_POINTER;
+ *aidl_return =
+ static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::UNEXPECTED_NULL_POINTER));
+ return Status::ok();
}
uid_t targetUid = getEffectiveUid(uid);
@@ -797,7 +920,8 @@
if (!is_granted_to(callingUid, targetUid)) {
ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
targetUid);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
Blob keyBlob;
@@ -813,7 +937,8 @@
*/
rc = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
AuthorizationSet keyCharacteristics;
// TODO write one shot stream buffer to avoid copying (twice here)
@@ -822,10 +947,12 @@
std::stringstream charStream(charBuffer);
keyCharacteristics.Deserialize(&charStream);
- outCharacteristics->softwareEnforced = keyCharacteristics.hidl_data();
- return rc;
+ outCharacteristics->softwareEnforced = KeymasterArguments(keyCharacteristics.hidl_data());
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
} else if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
auto hidlKeyBlob = blob2hidlVec(keyBlob);
@@ -838,53 +965,63 @@
if (!error.isOk()) {
return;
}
- *outCharacteristics = keyCharacteristics;
+ *outCharacteristics =
+ ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
};
- rc = KS_HANDLE_HIDL_ERROR(dev->getKeyCharacteristics(hidlKeyBlob, clientId, appData, hidlCb));
+ rc = KS_HANDLE_HIDL_ERROR(
+ dev->getKeyCharacteristics(hidlKeyBlob, clientId.getData(), appId.getData(), hidlCb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
AuthorizationSet upgradeParams;
- if (clientId.size()) {
- upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
+ if (clientId.getData().size()) {
+ upgradeParams.push_back(TAG_APPLICATION_ID, clientId.getData());
}
- if (appData.size()) {
- upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
+ if (appId.getData().size()) {
+ upgradeParams.push_back(TAG_APPLICATION_DATA, appId.getData());
}
rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
- rc = KS_HANDLE_HIDL_ERROR(
- dev->getKeyCharacteristics(upgradedHidlKeyBlob, clientId, appData, hidlCb));
+ rc = KS_HANDLE_HIDL_ERROR(dev->getKeyCharacteristics(
+ upgradedHidlKeyBlob, clientId.getData(), appId.getData(), hidlCb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
// Note that, on success, "error" will have been updated by the hidlCB callback.
// So it is fine to return "error" below.
}
- return error;
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(error));
+ return Status::ok();
}
-KeyStoreServiceReturnCode
-KeyStoreService::importKey(const String16& name, const hidl_vec<KeyParameter>& params,
- KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid, int flags,
- KeyCharacteristics* outCharacteristics) {
+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) {
+
uid = getEffectiveUid(uid);
KeyStoreServiceReturnCode rc =
checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
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);
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
bool usingFallback = false;
@@ -894,14 +1031,15 @@
KeyStoreServiceReturnCode error;
- auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
+ auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& keyBlob,
const KeyCharacteristics& keyCharacteristics) {
error = ret;
if (!error.isOk()) {
return;
}
-
- if (outCharacteristics) *outCharacteristics = keyCharacteristics;
+ if (outCharacteristics)
+ *outCharacteristics =
+ ::android::security::keymaster::KeyCharacteristics(keyCharacteristics);
// Write the key:
String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
@@ -909,7 +1047,8 @@
Blob ksBlob(&keyBlob[0], keyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
ksBlob.setFallback(usingFallback);
ksBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
- if (isAuthenticationBound(params) && !ksBlob.isCriticalToDeviceEncryption()) {
+ if (isAuthenticationBound(params.getParameters()) &&
+ !ksBlob.isCriticalToDeviceEncryption()) {
ksBlob.setSuperEncrypted(true);
}
ksBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -917,10 +1056,12 @@
error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(uid));
};
- rc = KS_HANDLE_HIDL_ERROR(dev->importKey(params, format, keyData, hidlCb));
+ rc = KS_HANDLE_HIDL_ERROR(
+ dev->importKey(params.getParameters(), KeyFormat(format), keyData, hidlCb));
// possible hidl error
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
// now check error from callback
if (!error.isOk()) {
@@ -928,26 +1069,33 @@
usingFallback = true;
auto fallback = mKeyStore->getFallbackDevice();
if (!fallback.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
- rc = KS_HANDLE_HIDL_ERROR(fallback.value()->importKey(params, format, keyData, hidlCb));
+ rc = KS_HANDLE_HIDL_ERROR(fallback.value()->importKey(params.getParameters(),
+ KeyFormat(format), keyData, hidlCb));
// possible hidl error
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
// now check error from callback
if (!error.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
}
// Write the characteristics:
String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
- AuthorizationSet opParams = params;
+ AuthorizationSet opParams = params.getParameters();
std::stringstream kcStream;
opParams.Serialize(&kcStream);
- if (kcStream.bad()) return ResponseCode::SYSTEM_ERROR;
+ if (kcStream.bad()) {
+ *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
+ return Status::ok();
+ }
auto kcBuf = kcStream.str();
Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), NULL, 0,
@@ -955,19 +1103,23 @@
charBlob.setFallback(usingFallback);
charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
- return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
+ *aidl_return =
+ static_cast<int32_t>(mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid)));
+
+ return Status::ok();
}
-void KeyStoreService::exportKey(const String16& name, KeyFormat format,
- const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
- int32_t uid, ExportResult* result) {
+Status KeyStoreService::exportKey(const String16& name, int32_t format,
+ const ::android::security::keymaster::KeymasterBlob& clientId,
+ const ::android::security::keymaster::KeymasterBlob& appId,
+ int32_t uid, ExportResult* result) {
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;
+ return Status::ok();
}
Blob keyBlob;
@@ -975,7 +1127,7 @@
result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
auto key = blob2hidlVec(keyBlob);
@@ -988,8 +1140,8 @@
}
result->exportData = keyMaterial;
};
- KeyStoreServiceReturnCode rc =
- KS_HANDLE_HIDL_ERROR(dev->exportKey(format, key, clientId, appData, hidlCb));
+ KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
+ dev->exportKey(KeyFormat(format), key, clientId.getData(), appId.getData(), hidlCb));
// Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
// callback hidlCb.
if (!rc.isOk()) {
@@ -998,25 +1150,26 @@
if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
AuthorizationSet upgradeParams;
- if (clientId.size()) {
- upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
+ if (clientId.getData().size()) {
+ upgradeParams.push_back(TAG_APPLICATION_ID, clientId.getData());
}
- if (appData.size()) {
- upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
+ if (appId.getData().size()) {
+ upgradeParams.push_back(TAG_APPLICATION_DATA, appId.getData());
}
result->resultCode = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
- result->resultCode = KS_HANDLE_HIDL_ERROR(
- dev->exportKey(format, upgradedHidlKeyBlob, clientId, appData, hidlCb));
+ result->resultCode = KS_HANDLE_HIDL_ERROR(dev->exportKey(
+ KeyFormat(format), upgradedHidlKeyBlob, clientId.getData(), appId.getData(), hidlCb));
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
}
+ return Status::ok();
}
static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
@@ -1025,25 +1178,25 @@
}
}
-void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
- bool pruneable, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int32_t uid,
- OperationResult* result) {
+Status KeyStoreService::begin(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) {
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;
+ return Status::ok();
}
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;
+ return Status::ok();
}
- if (!checkAllowedOperationParams(params)) {
+ if (!checkAllowedOperationParams(params.getParameters())) {
result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return;
+ return Status::ok();
}
Blob keyBlob;
String8 name8(name);
@@ -1052,25 +1205,25 @@
result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
}
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
auto key = blob2hidlVec(keyBlob);
auto& dev = mKeyStore->getDevice(keyBlob);
- AuthorizationSet opParams = params;
+ AuthorizationSet opParams = params.getParameters();
KeyCharacteristics characteristics;
result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
result->resultCode = upgradeKeyBlob(name, targetUid, opParams, &keyBlob);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
key = blob2hidlVec(keyBlob);
result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
}
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
const HardwareAuthToken* authToken = NULL;
@@ -1097,23 +1250,25 @@
persistedCharacteristics.Subtract(teeEnforced);
characteristics.softwareEnforced = persistedCharacteristics.hidl_data();
- auto authResult = getAuthToken(characteristics, 0, purpose, &authToken,
+ auto authResult = getAuthToken(characteristics, 0, KeyPurpose(purpose), &authToken,
/*failOnTokenMissing*/ false);
// If per-operation auth is needed we need to begin the operation and
// the client will need to authorize that operation before calling
// update. Any other auth issues stop here.
if (!authResult.isOk() && authResult != ResponseCode::OP_AUTH_NEEDED) {
result->resultCode = authResult;
- return;
+ return Status::ok();
}
addAuthTokenToParams(&opParams, authToken);
// Add entropy to the device first.
if (entropy.size()) {
- result->resultCode = addRngEntropy(entropy);
+ int32_t resultCode;
+ addRngEntropy(entropy, &resultCode); // binder error is not possible
+ result->resultCode = KeyStoreServiceReturnCode(resultCode);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
}
@@ -1122,7 +1277,7 @@
if (!enforcement_policy.CreateKeyId(key, &keyid)) {
ALOGE("Failed to create a key ID for authorization checking.");
result->resultCode = ErrorCode::UNKNOWN_ERROR;
- return;
+ return Status::ok();
}
// Check that all key authorization policy requirements are met.
@@ -1130,10 +1285,11 @@
key_auths.append(&characteristics.softwareEnforced[0],
&characteristics.softwareEnforced[characteristics.softwareEnforced.size()]);
- result->resultCode = enforcement_policy.AuthorizeOperation(
- purpose, keyid, key_auths, opParams, 0 /* op_handle */, true /* is_begin_operation */);
+ result->resultCode =
+ enforcement_policy.AuthorizeOperation(KeyPurpose(purpose), keyid, key_auths, opParams,
+ 0 /* op_handle */, true /* is_begin_operation */);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
// If there are more than kMaxOperations, abort the oldest operation that was started as
@@ -1155,7 +1311,8 @@
result->outParams = outParams;
};
- ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
+ ErrorCode rc =
+ KS_HANDLE_HIDL_ERROR(dev->begin(KeyPurpose(purpose), key, opParams.hidl_data(), hidlCb));
if (rc != ErrorCode::OK) {
ALOGW("Got error %d from begin()", rc);
}
@@ -1167,17 +1324,19 @@
if (!pruneOperation()) {
break;
}
- rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
+ rc = KS_HANDLE_HIDL_ERROR(
+ dev->begin(KeyPurpose(purpose), key, opParams.hidl_data(), hidlCb));
}
if (rc != ErrorCode::OK) {
result->resultCode = rc;
- return;
+ return Status::ok();
}
// Note: The operation map takes possession of the contents of "characteristics".
// It is safe to use characteristics after the following line but it will be empty.
- sp<IBinder> operationToken = mOperationMap.addOperation(
- result->handle, keyid, purpose, dev, appToken, std::move(characteristics), pruneable);
+ sp<IBinder> operationToken =
+ mOperationMap.addOperation(result->handle, keyid, KeyPurpose(purpose), dev, appToken,
+ std::move(characteristics), pruneable);
assert(characteristics.teeEnforced.size() == 0);
assert(characteristics.softwareEnforced.size() == 0);
result->token = operationToken;
@@ -1195,13 +1354,14 @@
}
// Other result fields were set in the begin operation's callback.
+ return Status::ok();
}
-void KeyStoreService::update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& data, OperationResult* result) {
- if (!checkAllowedOperationParams(params)) {
+Status KeyStoreService::update(const sp<IBinder>& token, const KeymasterArguments& params,
+ const ::std::vector<uint8_t>& data, OperationResult* result) {
+ if (!checkAllowedOperationParams(params.getParameters())) {
result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return;
+ return Status::ok();
}
km_device_t dev;
uint64_t handle;
@@ -1210,12 +1370,12 @@
const KeyCharacteristics* characteristics;
if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
- return;
+ return Status::ok();
}
- AuthorizationSet opParams = params;
+ AuthorizationSet opParams = params.getParameters();
result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
// Check that all key authorization policy requirements are met.
@@ -1225,11 +1385,12 @@
result->resultCode = enforcement_policy.AuthorizeOperation(
purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
- const hidl_vec<KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
+ const hidl_vec<KeyParameter>& outParams,
+ const ::std::vector<uint8_t>& output) {
result->resultCode = ret;
if (!result->resultCode.isOk()) {
return;
@@ -1239,21 +1400,22 @@
result->data = output;
};
- KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->update(handle, opParams.hidl_data(),
- data, hidlCb));
+ KeyStoreServiceReturnCode rc =
+ KS_HANDLE_HIDL_ERROR(dev->update(handle, opParams.hidl_data(), data, hidlCb));
// just a reminder: on success result->resultCode was set in the callback. So we only overwrite
// it if there was a communication error indicated by the ErrorCode.
if (!rc.isOk()) {
result->resultCode = rc;
}
+ return Status::ok();
}
-void KeyStoreService::finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
- OperationResult* result) {
- if (!checkAllowedOperationParams(params)) {
+Status KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArguments& params,
+ const ::std::vector<uint8_t>& signature,
+ const ::std::vector<uint8_t>& entropy, OperationResult* result) {
+ if (!checkAllowedOperationParams(params.getParameters())) {
result->resultCode = ErrorCode::INVALID_ARGUMENT;
- return;
+ return Status::ok();
}
km_device_t dev;
uint64_t handle;
@@ -1262,18 +1424,20 @@
const KeyCharacteristics* characteristics;
if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
- return;
+ return Status::ok();
}
- AuthorizationSet opParams = params;
+ AuthorizationSet opParams = params.getParameters();
result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
if (entropy.size()) {
- result->resultCode = addRngEntropy(entropy);
+ int resultCode;
+ addRngEntropy(entropy, &resultCode); // binder error is not possible
+ result->resultCode = KeyStoreServiceReturnCode(resultCode);
if (!result->resultCode.isOk()) {
- return;
+ return Status::ok();
}
}
@@ -1283,21 +1447,21 @@
&characteristics->softwareEnforced[characteristics->softwareEnforced.size()]);
result->resultCode = enforcement_policy.AuthorizeOperation(
purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
- if (!result->resultCode.isOk()) return;
+ if (!result->resultCode.isOk()) return Status::ok();
auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
- const hidl_vec<uint8_t>& output) {
+ const ::std::vector<uint8_t>& output) {
result->resultCode = ret;
if (!result->resultCode.isOk()) {
- return;
}
result->outParams = outParams;
result->data = output;
};
- KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->finish(
- handle, opParams.hidl_data(),
- hidl_vec<uint8_t>() /* TODO(swillden): wire up input to finish() */, signature, hidlCb));
+ KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
+ dev->finish(handle, opParams.hidl_data(),
+ ::std::vector<uint8_t>() /* TODO(swillden): wire up input to finish() */,
+ signature, hidlCb));
// Remove the operation regardless of the result
mOperationMap.removeOperation(token);
mAuthTokenTable.MarkCompleted(handle);
@@ -1307,55 +1471,66 @@
if (!rc.isOk()) {
result->resultCode = rc;
}
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
+Status KeyStoreService::abort(const sp<IBinder>& token, int32_t* aidl_return) {
km_device_t dev;
uint64_t handle;
KeyPurpose purpose;
km_id_t keyid;
if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, NULL)) {
- return ErrorCode::INVALID_OPERATION_HANDLE;
+ *aidl_return =
+ static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_OPERATION_HANDLE));
+ return Status::ok();
}
mOperationMap.removeOperation(token);
- ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->abort(handle));
+ ErrorCode error_code = KS_HANDLE_HIDL_ERROR(dev->abort(handle));
mAuthTokenTable.MarkCompleted(handle);
- return rc;
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(error_code));
+ return Status::ok();
}
-bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
+Status KeyStoreService::isOperationAuthorized(const sp<IBinder>& token, bool* aidl_return) {
km_device_t dev;
uint64_t handle;
const KeyCharacteristics* characteristics;
KeyPurpose purpose;
km_id_t keyid;
if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
- return false;
+ *aidl_return = false;
+ return Status::ok();
}
const HardwareAuthToken* authToken = NULL;
mOperationMap.getOperationAuthToken(token, &authToken);
AuthorizationSet ignored;
auto authResult = addOperationAuthTokenIfNeeded(token, &ignored);
- return authResult.isOk();
+ *aidl_return = authResult.isOk();
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
+Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
+ int32_t* aidl_return) {
+
// TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
// receive a HardwareAuthToken, rather than an opaque byte array.
if (!checkBinderPermission(P_ADD_AUTH)) {
ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
- return ResponseCode::PERMISSION_DENIED;
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
}
- if (length != sizeof(hw_auth_token_t)) {
- return ErrorCode::INVALID_ARGUMENT;
+ if (authTokenAsVector.size() != sizeof(hw_auth_token_t)) {
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+ return Status::ok();
}
hw_auth_token_t authToken;
- memcpy(reinterpret_cast<void*>(&authToken), token, sizeof(hw_auth_token_t));
+ memcpy(reinterpret_cast<void*>(&authToken), authTokenAsVector.data(), sizeof(hw_auth_token_t));
if (authToken.version != 0) {
- return ErrorCode::INVALID_ARGUMENT;
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+ return Status::ok();
}
std::unique_ptr<HardwareAuthToken> hidlAuthToken(new HardwareAuthToken);
@@ -1370,14 +1545,15 @@
"This function assumes token HMAC is 32 bytes, but it might not be.");
std::copy(authToken.hmac, authToken.hmac + sizeof(authToken.hmac), hidlAuthToken->hmac.data());
- // The table takes ownership of authToken.
- mAuthTokenTable.AddAuthenticationToken(hidlAuthToken.release());
- return ResponseCode::NO_ERROR;
+ mAuthTokenTable.AddAuthenticationToken(std::move(hidlAuthToken));
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
-bool isDeviceIdAttestationRequested(const hidl_vec<KeyParameter>& params) {
- for (size_t i = 0; i < params.size(); ++i) {
- switch (params[i].tag) {
+bool isDeviceIdAttestationRequested(const KeymasterArguments& params) {
+ const hardware::hidl_vec<KeyParameter> paramsVec = params.getParameters();
+ for (size_t i = 0; i < paramsVec.size(); ++i) {
+ switch (paramsVec[i].tag) {
case Tag::ATTESTATION_ID_BRAND:
case Tag::ATTESTATION_ID_DEVICE:
case Tag::ATTESTATION_ID_IMEI:
@@ -1394,35 +1570,36 @@
return false;
}
-KeyStoreServiceReturnCode KeyStoreService::attestKey(const String16& name,
- const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) {
- if (!outChain) {
- return ErrorCode::OUTPUT_PARAMETER_NULL;
- }
-
- if (!checkAllowedOperationParams(params)) {
- return ErrorCode::INVALID_ARGUMENT;
+Status KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
+ ::android::security::keymaster::KeymasterCertificateChain* chain,
+ 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();
}
if (isDeviceIdAttestationRequested(params)) {
// There is a dedicated attestDeviceIds() method for device ID attestation.
- return ErrorCode::INVALID_ARGUMENT;
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+ return Status::ok();
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
- AuthorizationSet mutableParams = params;
+ AuthorizationSet mutableParams = params.getParameters();
KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
Blob keyBlob;
String8 name8(name);
rc = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
KeyStoreServiceReturnCode error;
@@ -1431,54 +1608,65 @@
if (!error.isOk()) {
return;
}
- if (outChain) *outChain = certChain;
+ if (chain) {
+ *chain = KeymasterCertificateChain(certChain);
+ }
};
auto hidlKey = blob2hidlVec(keyBlob);
auto& dev = mKeyStore->getDevice(keyBlob);
rc = KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), hidlCb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::attestDeviceIds(const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) {
- if (!outChain) {
- return ErrorCode::OUTPUT_PARAMETER_NULL;
- }
+Status
+KeyStoreService::attestDeviceIds(const KeymasterArguments& params,
+ ::android::security::keymaster::KeymasterCertificateChain* chain,
+ int32_t* aidl_return) {
+ // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
- if (!checkAllowedOperationParams(params)) {
- return ErrorCode::INVALID_ARGUMENT;
+ if (!checkAllowedOperationParams(params.getParameters())) {
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+ return Status::ok();
}
if (!isDeviceIdAttestationRequested(params)) {
// There is an attestKey() method for attesting keys without device ID attestation.
- return ErrorCode::INVALID_ARGUMENT;
+ *aidl_return = static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
+ return Status::ok();
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
if (binder == 0) {
- return ErrorCode::CANNOT_ATTEST_IDS;
+ *aidl_return =
+ static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
+ return Status::ok();
}
if (!interface_cast<IPermissionController>(binder)->checkPermission(
String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
IPCThreadState::self()->getCallingPid(), callingUid)) {
- return ErrorCode::CANNOT_ATTEST_IDS;
+ *aidl_return =
+ static_cast<int32_t>(KeyStoreServiceReturnCode(ErrorCode::CANNOT_ATTEST_IDS));
+ return Status::ok();
}
- AuthorizationSet mutableParams = params;
+ AuthorizationSet mutableParams = params.getParameters();
KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
// Generate temporary key.
auto& dev = mKeyStore->getDevice();
KeyStoreServiceReturnCode error;
- hidl_vec<uint8_t> hidlKey;
+ ::std::vector<uint8_t> hidlKey;
AuthorizationSet keyCharacteristics;
keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
@@ -1486,7 +1674,7 @@
keyCharacteristics.push_back(TAG_DIGEST, Digest::SHA_2_256);
keyCharacteristics.push_back(TAG_NO_AUTH_REQUIRED);
keyCharacteristics.push_back(TAG_EC_CURVE, EcCurve::P_256);
- auto generateHidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+ auto generateHidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& hidlKeyBlob,
const KeyCharacteristics&) {
error = ret;
if (!error.isOk()) {
@@ -1497,10 +1685,12 @@
rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(keyCharacteristics.hidl_data(), generateHidlCb));
if (!rc.isOk()) {
- return rc;
+ *aidl_return = static_cast<int32_t>(rc);
+ return Status::ok();
}
if (!error.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
// Attest key and device IDs.
@@ -1509,27 +1699,31 @@
if (!error.isOk()) {
return;
}
- *outChain = certChain;
+ *chain = ::android::security::keymaster::KeymasterCertificateChain(certChain);
};
KeyStoreServiceReturnCode attestationRc =
- KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), attestHidlCb));
+ KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), attestHidlCb));
// Delete temporary key.
KeyStoreServiceReturnCode deletionRc = KS_HANDLE_HIDL_ERROR(dev->deleteKey(hidlKey));
if (!attestationRc.isOk()) {
- return attestationRc;
+ *aidl_return = static_cast<int32_t>(attestationRc);
+ return Status::ok();
}
if (!error.isOk()) {
- return error;
+ *aidl_return = static_cast<int32_t>(error);
+ return Status::ok();
}
- return deletionRc;
+ *aidl_return = static_cast<int32_t>(deletionRc);
+ return Status::ok();
}
-KeyStoreServiceReturnCode KeyStoreService::onDeviceOffBody() {
+Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
// TODO(tuckeris): add permission check. This should be callable from ClockworkHome only.
mAuthTokenTable.onDeviceOffBody();
- return ResponseCode::NO_ERROR;
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
}
/**
@@ -1541,7 +1735,8 @@
size_t op_count_before_abort = mOperationMap.getOperationCount();
// We mostly ignore errors from abort() because all we care about is whether at least
// one operation has been removed.
- int abort_error = abort(oldest);
+ int32_t abort_error;
+ abort(oldest, &abort_error);
if (mOperationMap.getOperationCount() >= op_count_before_abort) {
ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), abort_error);
return false;
@@ -1664,13 +1859,13 @@
km_device_t* dev,
const AuthorizationSet& params,
KeyCharacteristics* out) {
- hidl_vec<uint8_t> appId;
- hidl_vec<uint8_t> appData;
+ ::std::vector<uint8_t> appId;
+ ::std::vector<uint8_t> appData;
for (auto param : params) {
if (param.tag == Tag::APPLICATION_ID) {
appId = authorizationValue(TAG_APPLICATION_ID, param).value();
} else if (param.tag == Tag::APPLICATION_DATA) {
- appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
+ appId = authorizationValue(TAG_APPLICATION_DATA, param).value();
}
}
ErrorCode error = ErrorCode::OK;
@@ -1683,7 +1878,7 @@
if (out) *out = keyCharacteristics;
};
- ErrorCode rc = KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, appId, appData, hidlCb));
+ ErrorCode rc = KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, appId, appId, hidlCb));
if (rc != ErrorCode::OK) {
return rc;
}
@@ -1712,8 +1907,8 @@
for (size_t i = 0; i < characteristics.teeEnforced.size(); i++) {
allCharacteristics.push_back(characteristics.teeEnforced[i]);
}
- AuthTokenTable::Error err =
- mAuthTokenTable.FindAuthorization(allCharacteristics, purpose, handle, authToken);
+ AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization(
+ allCharacteristics, KeyPurpose(purpose), handle, authToken);
switch (err) {
case AuthTokenTable::OK:
case AuthTokenTable::AUTH_NOT_REQUIRED:
@@ -1721,7 +1916,7 @@
case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
case AuthTokenTable::AUTH_TOKEN_EXPIRED:
case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
- ALOGE("getAuthToken failed: %d", err); //STOPSHIP: debug only, to be removed
+ ALOGE("getAuthToken failed: %d", err); // STOPSHIP: debug only, to be removed
return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
case AuthTokenTable::OP_HANDLE_REQUIRED:
return failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
@@ -1779,14 +1974,16 @@
return ResponseCode::SYSTEM_ERROR;
}
-static NullOr<const Algorithm&>
-getKeyAlgoritmFromKeyCharacteristics(const KeyCharacteristics& characteristics) {
- for (size_t i = 0; i < characteristics.teeEnforced.size(); ++i) {
- auto algo = authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced[i]);
+static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
+ const ::android::security::keymaster::KeyCharacteristics& characteristics) {
+ for (size_t i = 0; i < characteristics.teeEnforced.getParameters().size(); ++i) {
+ auto algo =
+ authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced.getParameters()[i]);
if (algo.isOk()) return algo.value();
}
- for (size_t i = 0; i < characteristics.softwareEnforced.size(); ++i) {
- auto algo = authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced[i]);
+ for (size_t i = 0; i < characteristics.softwareEnforced.getParameters().size(); ++i) {
+ auto algo =
+ authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced.getParameters()[i]);
if (algo.isOk()) return algo.value();
}
return {};
@@ -1798,9 +1995,11 @@
params->push_back(TAG_PADDING, PaddingMode::NONE);
// Look up the algorithm of the key.
- KeyCharacteristics characteristics;
- auto rc = getKeyCharacteristics(name, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF,
- &characteristics);
+ ::android::security::keymaster::KeyCharacteristics characteristics;
+ int32_t result;
+ auto rc = getKeyCharacteristics(name, ::android::security::keymaster::KeymasterBlob(),
+ ::android::security::keymaster::KeymasterBlob(), UID_SELF,
+ &characteristics, &result);
if (!rc.isOk()) {
ALOGE("Failed to get key characteristics");
return;
@@ -1826,8 +2025,8 @@
sp<IBinder> appToken(new BBinder);
sp<IBinder> token;
- begin(appToken, name, purpose, true, inArgs.hidl_data(), hidl_vec<uint8_t>(), UID_SELF,
- &result);
+ begin(appToken, name, static_cast<int32_t>(purpose), true,
+ KeymasterArguments(inArgs.hidl_data()), ::std::vector<uint8_t>(), UID_SELF, &result);
if (!result.resultCode.isOk()) {
if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
ALOGW("Key not found");
@@ -1843,7 +2042,7 @@
hidl_vec<uint8_t> data_view;
do {
data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
- update(token, inArgs.hidl_data(), data_view, &result);
+ update(token, KeymasterArguments(inArgs.hidl_data()), data_view, &result);
if (result.resultCode != ResponseCode::NO_ERROR) {
ALOGW("Error in update: %d", int32_t(result.resultCode));
return translateResultToLegacyResult(result.resultCode);
@@ -1860,7 +2059,8 @@
return ResponseCode::SYSTEM_ERROR;
}
- finish(token, inArgs.hidl_data(), signature, hidl_vec<uint8_t>(), &result);
+ finish(token, KeymasterArguments(inArgs.hidl_data()), signature, ::std::vector<uint8_t>(),
+ &result);
if (result.resultCode != ResponseCode::NO_ERROR) {
ALOGW("Error in finish: %d", int32_t(result.resultCode));
return translateResultToLegacyResult(result.resultCode);
@@ -1883,7 +2083,8 @@
Blob* blob) {
// Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
String8 name8(name);
- ResponseCode responseCode = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
+ KeyStoreServiceReturnCode responseCode =
+ mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
if (responseCode != ResponseCode::NO_ERROR) {
return responseCode;
}
@@ -1893,7 +2094,7 @@
auto& dev = mKeyStore->getDevice(*blob);
KeyStoreServiceReturnCode error;
- auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+ auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
error = ret;
if (!error.isOk()) {
return;
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 4060bd1..81a0df1 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -17,11 +17,10 @@
#ifndef KEYSTORE_KEYSTORE_SERVICE_H_
#define KEYSTORE_KEYSTORE_SERVICE_H_
-#include <keystore/IKeystoreService.h>
-
-#include <keystore/authorization_set.h>
+#include <android/security/BnKeystoreService.h>
#include "auth_token_table.h"
+
#include "keystore.h"
#include "keystore_keymaster_enforcement.h"
#include "operation.h"
@@ -29,7 +28,13 @@
namespace keystore {
-class KeyStoreService : public android::BnKeystoreService, public android::IBinder::DeathRecipient {
+// Class provides implementation for generated BnKeystoreService.h based on
+// gen/aidl/android/security/BnKeystoreService.h generated from
+// 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,
+ android::IBinder::DeathRecipient {
typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
public:
@@ -37,39 +42,40 @@
void binderDied(const android::wp<android::IBinder>& who);
- KeyStoreServiceReturnCode getState(int32_t userId) override;
-
- KeyStoreServiceReturnCode get(const android::String16& name, int32_t uid,
- hidl_vec<uint8_t>* item) override;
- KeyStoreServiceReturnCode insert(const android::String16& name, const hidl_vec<uint8_t>& item,
- int targetUid, int32_t flags) override;
- KeyStoreServiceReturnCode del(const android::String16& name, int targetUid) override;
- KeyStoreServiceReturnCode exist(const android::String16& name, int targetUid) override;
- KeyStoreServiceReturnCode list(const android::String16& prefix, int targetUid,
- android::Vector<android::String16>* matches) override;
-
- KeyStoreServiceReturnCode reset() override;
-
- KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
- const android::String16& password) override;
- KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override;
- KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override;
-
- KeyStoreServiceReturnCode lock(int32_t userId) override;
- KeyStoreServiceReturnCode unlock(int32_t userId, const android::String16& pw) override;
-
- bool isEmpty(int32_t userId) override;
-
- KeyStoreServiceReturnCode
- generate(const android::String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
- int32_t flags, android::Vector<android::sp<android::KeystoreArg>>* args) override;
- KeyStoreServiceReturnCode import(const android::String16& name, const hidl_vec<uint8_t>& data,
- int targetUid, int32_t flags) override;
- KeyStoreServiceReturnCode sign(const android::String16& name, const hidl_vec<uint8_t>& data,
- hidl_vec<uint8_t>* out) override;
- KeyStoreServiceReturnCode verify(const android::String16& name, const hidl_vec<uint8_t>& data,
- const hidl_vec<uint8_t>& signature) override;
-
+ ::android::binder::Status getState(int32_t userId, int32_t* _aidl_return) override;
+ ::android::binder::Status get(const ::android::String16& name, int32_t uid,
+ ::std::vector<uint8_t>* _aidl_return) override;
+ ::android::binder::Status insert(const ::android::String16& name,
+ const ::std::vector<uint8_t>& item, int32_t uid, int32_t flags,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status del(const ::android::String16& name, int32_t uid,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status exist(const ::android::String16& name, int32_t uid,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status list(const ::android::String16& namePrefix, int32_t uid,
+ ::std::vector<::android::String16>* _aidl_return) override;
+ ::android::binder::Status reset(int32_t* _aidl_return) override;
+ ::android::binder::Status onUserPasswordChanged(int32_t userId,
+ const ::android::String16& newPassword,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status lock(int32_t userId, int32_t* _aidl_return) override;
+ ::android::binder::Status unlock(int32_t userId, const ::android::String16& userPassword,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status isEmpty(int32_t userId, int32_t* _aidl_return) override;
+ ::android::binder::Status generate(const ::android::String16& name, int32_t uid,
+ int32_t keyType, int32_t keySize, int32_t flags,
+ const ::android::security::KeystoreArguments& args,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status import_key(const ::android::String16& name,
+ const ::std::vector<uint8_t>& data, int32_t uid,
+ int32_t flags, int32_t* _aidl_return) override;
+ ::android::binder::Status sign(const ::android::String16& name,
+ const ::std::vector<uint8_t>& data,
+ ::std::vector<uint8_t>* _aidl_return) override;
+ ::android::binder::Status verify(const ::android::String16& name,
+ const ::std::vector<uint8_t>& data,
+ const ::std::vector<uint8_t>& signature,
+ int32_t* _aidl_return) override;
/*
* TODO: The abstraction between things stored in hardware and regular blobs
* of data stored on the filesystem should be moved down to keystore itself.
@@ -81,60 +87,80 @@
* "del_key" since the Java code doesn't really communicate what it's
* intentions are.
*/
- KeyStoreServiceReturnCode get_pubkey(const android::String16& name,
- hidl_vec<uint8_t>* pubKey) override;
-
- android::String16 grant(const android::String16& name, int32_t granteeUid) override;
- KeyStoreServiceReturnCode ungrant(const android::String16& name, int32_t granteeUid) override;
-
- int64_t getmtime(const android::String16& name, int32_t uid) override;
-
- KeyStoreServiceReturnCode duplicate(const android::String16& srcKey, int32_t srcUid,
- const android::String16& destKey, int32_t destUid) override;
-
- int32_t is_hardware_backed(const android::String16& keyType) override;
-
- KeyStoreServiceReturnCode clear_uid(int64_t targetUid64) override;
-
- KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override;
- KeyStoreServiceReturnCode generateKey(const android::String16& name,
- const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int uid, int flags,
- KeyCharacteristics* outCharacteristics) override;
- KeyStoreServiceReturnCode
- getKeyCharacteristics(const android::String16& name, const hidl_vec<uint8_t>& clientId,
- const hidl_vec<uint8_t>& appData, int32_t uid,
- KeyCharacteristics* outCharacteristics) override;
- KeyStoreServiceReturnCode importKey(const android::String16& name,
- const hidl_vec<KeyParameter>& params, KeyFormat format,
- const hidl_vec<uint8_t>& keyData, int uid, int flags,
- KeyCharacteristics* outCharacteristics) override;
- void exportKey(const android::String16& name, KeyFormat format,
- const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData, int32_t uid,
- android::ExportResult* result) override;
- void begin(const sp<android::IBinder>& appToken, const android::String16& name,
- KeyPurpose purpose, bool pruneable, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& entropy, int32_t uid,
- android::OperationResult* result) override;
- void update(const sp<android::IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& data, android::OperationResult* result) override;
- void finish(const sp<android::IBinder>& token, const hidl_vec<KeyParameter>& params,
- const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
- android::OperationResult* result) override;
- KeyStoreServiceReturnCode abort(const sp<android::IBinder>& token) override;
-
- bool isOperationAuthorized(const sp<android::IBinder>& token) override;
-
- KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override;
-
- KeyStoreServiceReturnCode attestKey(const android::String16& name,
- const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) override;
-
- KeyStoreServiceReturnCode attestDeviceIds(const hidl_vec<KeyParameter>& params,
- hidl_vec<hidl_vec<uint8_t>>* outChain) override;
-
- KeyStoreServiceReturnCode onDeviceOffBody() override;
+ ::android::binder::Status get_pubkey(const ::android::String16& name,
+ ::std::vector<uint8_t>* _aidl_return) override;
+ ::android::binder::Status grant(const ::android::String16& name, int32_t granteeUid,
+ ::android::String16* _aidl_return) override;
+ ::android::binder::Status ungrant(const ::android::String16& name, int32_t granteeUid,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status getmtime(const ::android::String16& name, int32_t uid,
+ int64_t* _aidl_return) override;
+ ::android::binder::Status duplicate(const ::android::String16& srcKey, int32_t srcUid,
+ const ::android::String16& destKey, int32_t destUid,
+ int32_t* _aidl_return) override;
+ ::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* _aidl_return) override;
+ ::android::binder::Status
+ generateKey(const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterArguments& arguments,
+ const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
+ ::android::security::keymaster::KeyCharacteristics* characteristics,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status
+ getKeyCharacteristics(const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterBlob& clientId,
+ const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
+ ::android::security::keymaster::KeyCharacteristics* characteristics,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status
+ importKey(const ::android::String16& alias,
+ const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
+ const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
+ ::android::security::keymaster::KeyCharacteristics* characteristics,
+ int32_t* _aidl_return) override;
+ ::android::binder::Status
+ exportKey(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;
+ ::android::binder::Status
+ begin(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;
+ ::android::binder::Status
+ update(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;
+ ::android::binder::Status
+ finish(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;
+ ::android::binder::Status isOperationAuthorized(const ::android::sp<::android::IBinder>& token,
+ bool* _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 onDeviceOffBody(int32_t* _aidl_return) override;
private:
static const int32_t UID_SELF = -1;
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index 4cee57d..c27ec6b 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -29,6 +29,8 @@
#include <hardware/hw_auth_token.h>
#include <list>
+#include <keystore/keystore_hidl_support.h>
+
namespace keystore {
class AccessTimeMap {
@@ -482,12 +484,11 @@
sizeof(hw_auth_token_t), auth_token_blob.value().size());
return false;
}
-
- hw_auth_token_t auth_token;
- memcpy(&auth_token, &auth_token_blob.value()[0], sizeof(hw_auth_token_t));
- if (auth_token.version != HW_AUTH_TOKEN_VERSION) {
+ uint8_t auth_token_version = auth_token_blob.value()[0];
+ HardwareAuthToken auth_token = hidlVec2AuthToken(auth_token_blob.value());
+ if (auth_token_version != HW_AUTH_TOKEN_VERSION) {
ALOGE("Bug: Auth token is the version %hhu (or is not an auth token). Expected %d",
- auth_token.version, HW_AUTH_TOKEN_VERSION);
+ auth_token_version, HW_AUTH_TOKEN_VERSION);
return false;
}
@@ -502,9 +503,9 @@
return false;
}
- if (user_secure_id != auth_token.user_id && user_secure_id != auth_token.authenticator_id) {
+ if (user_secure_id != auth_token.userId && user_secure_id != auth_token.authenticatorId) {
ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64,
- auth_token.user_id, auth_token.authenticator_id, user_secure_id);
+ auth_token.userId, auth_token.authenticatorId, user_secure_id);
return false;
}
@@ -513,11 +514,11 @@
return false;
}
- assert(auth_set[auth_type_index].tag == KM_TAG_USER_AUTH_TYPE);
+ assert(auth_set[auth_type_index].tag == TAG_USER_AUTH_TYPE);
auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]);
if (!key_auth_type_mask.isOk()) return false;
- uint32_t token_auth_type = ntoh(auth_token.authenticator_type);
+ uint32_t token_auth_type = ntoh(auth_token.authenticatorType);
if ((uint32_t(key_auth_type_mask.value()) & token_auth_type) == 0) {
ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
key_auth_type_mask.value(), token_auth_type);
@@ -525,7 +526,7 @@
}
if (auth_timeout_index != -1 && is_begin_operation) {
- assert(auth_set[auth_timeout_index].tag == KM_TAG_AUTH_TIMEOUT);
+ assert(auth_set[auth_timeout_index].tag == TAG_AUTH_TIMEOUT);
auto auth_token_timeout =
authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]);
if (!auth_token_timeout.isOk()) return false;
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
index 4f22f01..28d546a 100644
--- a/keystore/keymaster_enforcement.h
+++ b/keystore/keymaster_enforcement.h
@@ -121,7 +121,7 @@
/*
* Returns true if the specified auth_token is older than the specified timeout.
*/
- virtual bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const = 0;
+ virtual bool auth_token_timed_out(const HardwareAuthToken& token, uint32_t timeout) const = 0;
/*
* Get current time in seconds from some starting point. This value is used to compute relative
@@ -138,7 +138,7 @@
* Returns true if the specified auth_token has a valid signature, or if signature validation is
* not available.
*/
- virtual bool ValidateTokenSignature(const hw_auth_token_t& token) const = 0;
+ virtual bool ValidateTokenSignature(const HardwareAuthToken& token) const = 0;
private:
ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index a61ef73..331151e 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -26,9 +26,8 @@
#include <utils/String16.h>
#include <utils/String8.h>
-#include <keystore/IKeystoreService.h>
-
#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <android/security/IKeystoreService.h>
#include "keystore_utils.h"
#include "permissions.h"
@@ -131,8 +130,8 @@
}
}
-android::String8 KeyStore::getKeyNameForUid(
- const android::String8& keyName, uid_t uid, const BlobType type) {
+android::String8 KeyStore::getKeyNameForUid(const android::String8& keyName, uid_t uid,
+ const BlobType type) {
std::vector<char> encoded(encode_key_length(keyName) + 1); // add 1 for null char
encode_key(encoded.data(), keyName);
if (type == TYPE_KEY_CHARACTERISTICS) {
@@ -142,8 +141,8 @@
}
}
-android::String8 KeyStore::getKeyNameForUidWithDir(
- const android::String8& keyName, uid_t uid, const BlobType type) {
+android::String8 KeyStore::getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
+ const BlobType type) {
std::vector<char> encoded(encode_key_length(keyName) + 1); // add 1 for null char
encode_key(encoded.data(), keyName);
@@ -157,7 +156,7 @@
}
NullOr<android::String8> KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
- const BlobType type) {
+ const BlobType type) {
android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type));
if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
@@ -172,14 +171,14 @@
// They might be using a granted key.
auto grant = mGrants.get(uid, alias.string());
if (grant) {
- filepath8 = String8::format("%s/%s", grant->owner_dir_name_.c_str(),
- getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str());
+ filepath8 = String8::format(
+ "%s/%s", grant->owner_dir_name_.c_str(),
+ getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str());
if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
}
return {};
}
-
void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
android::String8 prefix("");
android::Vector<android::String16> aliases;
@@ -224,9 +223,9 @@
// del() will fail silently if no cached characteristics are present for this alias.
android::String8 chr_filename(aliases[i]);
- chr_filename = android::String8::format("%s/%s", userState->getUserDirName(),
- getKeyName(chr_filename,
- TYPE_KEY_CHARACTERISTICS).string());
+ chr_filename = android::String8::format(
+ "%s/%s", userState->getUserDirName(),
+ getKeyName(chr_filename, TYPE_KEY_CHARACTERISTICS).string());
del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId);
}
}
@@ -351,8 +350,8 @@
// remove possible grants
mGrants.removeAllGrantsToKey(uid, alias);
}
- return (unlink(filename) && errno != ENOENT) ?
- ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
+ return (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR
+ : ResponseCode::NO_ERROR;
}
if (rc != ResponseCode::NO_ERROR) {
return rc;
@@ -368,8 +367,8 @@
return ResponseCode::SYSTEM_ERROR;
}
- rc = (unlink(filename) && errno != ENOENT) ?
- ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
+ rc =
+ (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
if (rc == ResponseCode::NO_ERROR && keyBlob.getType() != ::TYPE_KEY_CHARACTERISTICS) {
// now that we have successfully deleted a key, let's make sure there are no stale grants
@@ -419,8 +418,8 @@
static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filepath) {
auto filenamebase = filepath.find_last_of('/');
- std::string filename = filenamebase == std::string::npos ? filepath :
- filepath.substr(filenamebase + 1);
+ std::string filename =
+ filenamebase == std::string::npos ? filepath : filepath.substr(filenamebase + 1);
if (filename[0] == '.') return {};
@@ -524,8 +523,8 @@
hidl_vec<uint8_t> blob;
ErrorCode error;
- auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
- const KeyCharacteristics& /* ignored */) {
+ auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
+ const KeyCharacteristics& /* ignored */) {
error = ret;
if (error != ErrorCode::OK) return;
blob = keyBlob;
@@ -533,7 +532,7 @@
auto input = blob2hidlVec(key, keyLen);
ErrorCode rc = KS_HANDLE_HIDL_ERROR(
- mDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb));
+ mDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb));
if (rc != ErrorCode::OK) return ResponseCode::SYSTEM_ERROR;
if (error != ErrorCode::OK) {
ALOGE("Keymaster error %d importing key pair", error);
@@ -556,14 +555,12 @@
}
bool isSecure = false;
- auto hidlcb = [&] (bool _isSecure, bool, bool, bool, bool, const hidl_string&,
- const hidl_string&) {
- isSecure = _isSecure;
- };
+ auto hidlcb = [&](bool _isSecure, bool, bool, bool, bool, const hidl_string&,
+ const hidl_string&) { isSecure = _isSecure; };
auto rc = mDevice->getHardwareFeatures(hidlcb);
if (!rc.isOk()) {
ALOGE("Communication with keymaster HAL failed while retrieving hardware features (%s)",
- rc.description().c_str());
+ rc.description().c_str());
return false;
}
return isSecure;
@@ -574,8 +571,7 @@
auto filepath8 = getBlobFileNameIfExists(keyName, uid, type);
uid_t userId = get_user_id(uid);
- if (filepath8.isOk())
- return get(filepath8.value().string(), keyBlob, type, userId);
+ if (filepath8.isOk()) return get(filepath8.value().string(), keyBlob, type, userId);
return ResponseCode::KEY_NOT_FOUND;
}
diff --git a/keystore/keystore.h b/keystore/keystore.h
index a0b747f..a5ffd2f 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -24,8 +24,8 @@
#include <utils/Vector.h>
#include "blob.h"
-#include "include/keystore/keymaster_tags.h"
#include "grant_store.h"
+#include "include/keystore/keymaster_tags.h"
using ::keystore::NullOr;
@@ -71,7 +71,7 @@
android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
const BlobType type);
NullOr<android::String8> getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
- const BlobType type);
+ const BlobType type);
/*
* Delete entries owned by userId. If keepUnencryptedEntries is true
@@ -135,7 +135,9 @@
::keystore::GrantStore mGrants;
- typedef struct { uint32_t version; } keystore_metadata_t;
+ typedef struct {
+ uint32_t version;
+ } keystore_metadata_t;
keystore_metadata_t mMetaData;
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
index 3137ae1..1927cfc 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
@@ -21,9 +21,17 @@
#include "keystore_aidl_hidl_marshalling_utils.h"
#include <keystore/keystore_hidl_support.h>
+#include "include/keystore/ExportResult.h"
+#include "include/keystore/KeyCharacteristics.h"
+#include "include/keystore/KeymasterBlob.h"
+#include "include/keystore/KeymasterCertificateChain.h"
+#include "include/keystore/KeystoreArg.h"
+
namespace keystore {
+// reads byte[]
hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
+
ssize_t length = in.readInt32();
if (length <= 0) {
return {};
@@ -43,44 +51,23 @@
if (!size) return ::android::OK;
- return out->write(&blob[0], size);
+ return out->write(blob.data(), size);
}
-NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace) {
- // The distinction from readKeymasterBob is that the byte array is not prefixed with a presence
- // value, instead a -1 in the length field indicates NULL.
- ssize_t length = in.readInt32();
- if (length < 0) {
- return {};
- }
+android::status_t writeKeymasterBlob(const ::std::vector<int32_t>& blob, android::Parcel* out) {
- if (length == 0) {
- return hidl_vec<uint8_t>();
- }
-
- const void* buf = in.readInplace(length);
- if (!buf) return hidl_vec<uint8_t>();
-
- return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
-}
-
-android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
- android::Parcel* out) {
- if (!blob.isOk()) {
- return out->writeInt32(-1);
- }
- int32_t size =
- int32_t(std::min<size_t>(blob.value().size(), std::numeric_limits<int32_t>::max()));
+ int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
auto rc = out->writeInt32(size);
if (rc != ::android::OK) return rc;
if (!size) return ::android::OK;
- return out->write(&blob.value()[0], size);
+ return out->write(blob.data(), size);
}
NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
+ // Method must be in sync with KeymasterArgument.java
if (in.readInt32() == 0) {
return {};
}
@@ -105,7 +92,7 @@
break;
case TagType::BIGNUM:
case TagType::BYTES:
- result.blob = readKeymasterBlob(in);
+ result.blob = readKeymasterBlob(in); // byte array
break;
default:
ALOGE("Unsupported KeyParameter tag %d", tag);
@@ -115,6 +102,9 @@
}
android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
+ // Method must be in sync with with KeymasterArgument.java
+ // Presence flag must be written by caller.
+
auto tag = param.tag;
auto rc = out->writeInt32(uint32_t(tag));
if (rc != ::android::OK) return rc;
@@ -146,7 +136,8 @@
}
hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
- ssize_t length = in.readInt32();
+
+ ssize_t length = in.readInt32(); // -1 for null
size_t ulength = (size_t)length;
if (length < 0) {
ulength = 0;
@@ -171,7 +162,7 @@
auto rc = out->writeInt32(size);
if (rc != ::android::OK) return rc;
for (int32_t i = 0; i < size; ++i) {
- rc = out->writeInt32(1);
+ rc = out->writeInt32(1); // writeTypedObject presence flag.
if (rc != ::android::OK) return rc;
rc = writeKeyParameterToParcel(params[i], out);
if (rc != ::android::OK) return rc;
@@ -179,21 +170,6 @@
return rc;
}
-KeyCharacteristics readKeyCharacteristicsFromParcel(const android::Parcel& in) {
- KeyCharacteristics result;
- result.softwareEnforced = readParamSetFromParcel(in);
- result.teeEnforced = readParamSetFromParcel(in);
- return result;
-}
-
-android::status_t writeKeyCharacteristicsToParcel(const KeyCharacteristics& keyChara,
- android::Parcel* out) {
- auto rc = writeParamSetToParcel(keyChara.softwareEnforced, out);
- if (rc != ::android::OK) return rc;
-
- return writeParamSetToParcel(keyChara.teeEnforced, out);
-}
-
hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
hidl_vec<hidl_vec<uint8_t>> result;
@@ -209,7 +185,7 @@
result[i] = readKeymasterBlob(in);
}
return result;
-}
+};
android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
android::Parcel* out) {
@@ -222,4 +198,63 @@
}
return rc;
}
+
+}; // namespace keystore
+
+// Implementation for keystore parcelables.
+// TODO: split implementation into separate classes
+namespace android {
+namespace security {
+namespace keymaster {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::status_t;
+
+ExportResult::ExportResult() : resultCode() {}
+
+ExportResult::~ExportResult() {}
+
+status_t ExportResult::readFromParcel(const Parcel* inn) {
+ const Parcel& in = *inn;
+ resultCode = ErrorCode(in.readInt32());
+ exportData = keystore::readKeymasterBlob(in);
+ return OK;
}
+
+status_t ExportResult::writeToParcel(Parcel* out) const {
+ out->writeInt32(resultCode);
+ return keystore::writeKeymasterBlob(exportData, out);
+}
+
+status_t KeyCharacteristics::readFromParcel(const Parcel* in) {
+ softwareEnforced.readFromParcel(in);
+ return teeEnforced.readFromParcel(in);
+}
+
+status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
+ softwareEnforced.writeToParcel(out);
+ return teeEnforced.writeToParcel(out);
+}
+
+status_t KeymasterBlob::readFromParcel(const Parcel* in) {
+ data_ = keystore::readKeymasterBlob(*in, true /* in place */);
+ return OK;
+}
+
+status_t KeymasterBlob::writeToParcel(Parcel* out) const {
+ return keystore::writeKeymasterBlob(data_, out);
+}
+
+status_t KeymasterCertificateChain::readFromParcel(const Parcel* in) {
+ chain = keystore::readCertificateChainFromParcel(*in);
+ return OK;
+}
+
+status_t KeymasterCertificateChain::writeToParcel(Parcel* out) const {
+ return keystore::writeCertificateChainToParcel(chain, out);
+}
+
+} // namespace keymaster
+} // namespace security
+
+} // namespace android
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
index fcd02ae..61f1ad1 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.h
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.h
@@ -71,13 +71,7 @@
hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in);
android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params, android::Parcel* out);
-KeyCharacteristics readKeyCharacteristicsFromParcel(const android::Parcel& in);
-android::status_t writeKeyCharacteristicsToParcel(const KeyCharacteristics& keyChara,
- android::Parcel* out);
-
hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in);
-android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
- android::Parcel* out);
}
#endif // KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index 24af024..1e100fc 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -18,8 +18,9 @@
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
+#include <vector>
-#include <keystore/IKeystoreService.h>
+#include <android/security/IKeystoreService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -27,6 +28,7 @@
using namespace android;
using namespace keystore;
+using android::security::IKeystoreService;
static const char* responses[] = {
NULL,
@@ -48,7 +50,8 @@
#define NO_ARG_INT_RETURN(cmd) \
do { \
if (strcmp(argv[1], #cmd) == 0) { \
- int32_t ret = service->cmd(); \
+ int32_t ret = -1; \
+ service->cmd(&ret); \
if (ret < 0) { \
fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
return 1; \
@@ -66,7 +69,8 @@
fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
return 1; \
} \
- int32_t ret = service->cmd(String16(argv[2])); \
+ int32_t ret = -1; \
+ service->cmd(String16(argv[2]), &ret); \
if (ret < 0) { \
fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
return 1; \
@@ -84,7 +88,8 @@
fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
return 1; \
} \
- int32_t ret = service->cmd(atoi(argv[2])); \
+ int32_t ret = -1; \
+ service->cmd(atoi(argv[2]), &ret); \
if (ret < 0) { \
fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
return 1; \
@@ -107,7 +112,8 @@
uid = atoi(argv[3]); \
fprintf(stderr, "Running as uid %d\n", uid); \
} \
- int32_t ret = service->cmd(String16(argv[2]), uid); \
+ int32_t ret = -1; \
+ service->cmd(String16(argv[2]), uid, &ret); \
if (ret < 0) { \
fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
return 1; \
@@ -125,18 +131,15 @@
fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
return 1; \
} \
- hidl_vec<uint8_t> data; \
+ std::vector<uint8_t> data; \
int uid = -1; \
if (argc > 3) { \
uid = atoi(argv[3]); \
fprintf(stderr, "Running as uid %d\n", uid); \
} \
- int32_t ret = service->cmd(String16(argv[2]), uid, &data); \
- if (ret < 0) { \
- fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
- return 1; \
- } else if (ret != ::NO_ERROR) { \
- fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
+ ::android::binder::Status ret = service->cmd(String16(argv[2]), uid, &data); \
+ if (!ret.isOk()) { \
+ fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
return 1; \
} else { \
fwrite(&data[0], data.size(), 1, stdout); \
@@ -146,7 +149,7 @@
} \
} while (0)
-#define STING_ARG_DATA_STDIN_INT_RETURN(cmd) \
+#define STRING_ARG_DATA_STDIN_INT_RETURN(cmd) \
do { \
if (strcmp(argv[1], #cmd) == 0) { \
if (argc < 3) { \
@@ -156,7 +159,8 @@
uint8_t* data; \
size_t dataSize; \
read_input(&data, &dataSize); \
- int32_t ret = service->cmd(String16(argv[2]), data, dataSize); \
+ int32_t ret = -1; \
+ service->cmd(String16(argv[2]), data, dataSize, &ret); \
if (ret < 0) { \
fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
return 1; \
@@ -174,13 +178,10 @@
fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
return 1; \
} \
- hidl_vec<uint8_t> data; \
- int32_t ret = service->cmd(String16(argv[2]), &data); \
- if (ret < 0) { \
- fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
- return 1; \
- } else if (ret != ::NO_ERROR) { \
- fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
+ std::vector<uint8_t> data; \
+ ::android::binder::Status ret = service->cmd(String16(argv[2]), &data); \
+ if (!ret.isOk()) { \
+ fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
return 1; \
} else { \
fwrite(&data[0], data.size(), 1, stdout); \
@@ -191,16 +192,14 @@
} while (0)
static int list(const sp<IKeystoreService>& service, const String16& name, int uid) {
- Vector<String16> matches;
- int32_t ret = service->list(name, uid, &matches);
- if (ret < 0) {
- fprintf(stderr, "list: could not connect: %d\n", ret);
- return 1;
- } else if (ret != ::NO_ERROR) {
- fprintf(stderr, "list: %s (%d)\n", responses[ret], ret);
+ std::vector<String16> matches;
+ ::android::binder::Status ret = service->list(name, uid, &matches);
+
+ if (!ret.isOk()) {
+ fprintf(stderr, "list: exception (%d)\n", ret.exceptionCode());
return 1;
} else {
- Vector<String16>::const_iterator it = matches.begin();
+ std::vector<String16>::const_iterator it = matches.begin();
for (; it != matches.end(); ++it) {
printf("%s\n", String8(*it).string());
}
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index f9df134..99fe606 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -19,10 +19,10 @@
#include <string>
#include <vector>
+#include <android/security/IKeystoreService.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/IServiceManager.h>
-#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h>
#include <log/log.h>
#include <utils/String16.h>
@@ -32,13 +32,6 @@
#include <keystore/authorization_set.h>
#include <keystore/keystore_hidl_support.h>
-using android::ExportResult;
-using keystore::KeyCharacteristics;
-using android::OperationResult;
-using android::String16;
-using keystore::AuthorizationSet;
-using keystore::AuthorizationSetBuilder;
-
namespace {
// Use the UID of the current process.
@@ -49,6 +42,13 @@
constexpr uint32_t kHMACKeySize = 256; // bits
constexpr uint32_t kHMACOutputSize = 256; // bits
+using android::String16;
+using android::security::keymaster::ExportResult;
+using android::security::keymaster::OperationResult;
+using keystore::AuthorizationSet;
+using keystore::AuthorizationSetBuilder;
+using keystore::KeyCharacteristics;
+using keystore::KeyStoreServiceReturnCode;
} // namespace
namespace keystore {
@@ -56,7 +56,7 @@
KeystoreClientImpl::KeystoreClientImpl() {
service_manager_ = android::defaultServiceManager();
keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
- keystore_ = android::interface_cast<android::IKeystoreService>(keystore_binder_);
+ keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
}
bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
@@ -86,7 +86,7 @@
return false;
}
auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
- if (!init_vector_blob.isOk()){
+ if (!init_vector_blob.isOk()) {
ALOGE("Encrypt: Missing initialization vector.");
return false;
}
@@ -154,8 +154,7 @@
AuthorizationSet* output_parameters,
std::string* output_data) {
uint64_t handle;
- auto result =
- beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
+ auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
if (!result.isOk()) {
ALOGE("BeginOperation failed: %d", int32_t(result));
return false;
@@ -178,26 +177,33 @@
return true;
}
-KeyStoreNativeReturnCode KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
- return keystore_->addRngEntropy(blob2hidlVec(entropy));
+KeyStoreNativeReturnCode
+KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
+ int32_t result;
+ auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ return KeyStoreNativeReturnCode(result);
}
-KeyStoreNativeReturnCode KeystoreClientImpl::generateKey(const std::string& key_name,
- const AuthorizationSet& key_parameters,
- AuthorizationSet* hardware_enforced_characteristics,
- AuthorizationSet* software_enforced_characteristics) {
+KeyStoreNativeReturnCode
+KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
+ AuthorizationSet* hardware_enforced_characteristics,
+ AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
- KeyCharacteristics characteristics;
- auto result =
- keystore_->generateKey(key_name16, key_parameters.hidl_data(), hidl_vec<uint8_t>(),
- kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
+ ::android::security::keymaster::KeyCharacteristics characteristics;
+ int32_t result;
+ auto binder_result = keystore_->generateKey(
+ key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
+ hidl_vec<uint8_t>() /* entropy */, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics,
+ &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
/* 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.teeEnforced;
- *software_enforced_characteristics = characteristics.softwareEnforced;
- return result;
+ *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+ *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
+ return KeyStoreNativeReturnCode(result);
}
KeyStoreNativeReturnCode
@@ -205,66 +211,80 @@
AuthorizationSet* hardware_enforced_characteristics,
AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
- KeyCharacteristics characteristics;
- auto result = keystore_->getKeyCharacteristics(key_name16, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
- kDefaultUID, &characteristics);
+ ::android::security::keymaster::KeyCharacteristics characteristics;
+ int32_t result;
+ auto binder_result = keystore_->getKeyCharacteristics(
+ key_name16, android::security::keymaster::KeymasterBlob(),
+ android::security::keymaster::KeymasterBlob(), kDefaultUID, &characteristics, &result);
/* 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.teeEnforced;
- *software_enforced_characteristics = characteristics.softwareEnforced;
- return result;
+ *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+ *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
+ return KeyStoreNativeReturnCode(result);
}
-KeyStoreNativeReturnCode KeystoreClientImpl::importKey(const std::string& key_name,
- const AuthorizationSet& key_parameters,
- KeyFormat key_format,
- const std::string& key_data,
- AuthorizationSet* hardware_enforced_characteristics,
- AuthorizationSet* software_enforced_characteristics) {
+KeyStoreNativeReturnCode
+KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
+ KeyFormat key_format, const std::string& key_data,
+ AuthorizationSet* hardware_enforced_characteristics,
+ AuthorizationSet* software_enforced_characteristics) {
String16 key_name16(key_name.data(), key_name.size());
auto hidlKeyData = blob2hidlVec(key_data);
- KeyCharacteristics characteristics;
- auto result = keystore_->importKey(key_name16, key_parameters.hidl_data(), key_format,
- hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
-
+ ::android::security::keymaster::KeyCharacteristics characteristics;
+ int32_t result;
+ 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);
/* 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.teeEnforced;
- *software_enforced_characteristics = characteristics.softwareEnforced;
- return result;
+ *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+ *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
+ return KeyStoreNativeReturnCode(result);
}
KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
- const std::string& key_name, std::string* export_data) {
+ const std::string& key_name,
+ std::string* export_data) {
String16 key_name16(key_name.data(), key_name.size());
ExportResult export_result;
- keystore_->exportKey(key_name16, export_format, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
- kDefaultUID, &export_result);
+ auto binder_result = keystore_->exportKey(
+ key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
+ android::security::keymaster::KeymasterBlob(), kDefaultUID, &export_result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
*export_data = hidlVec2String(export_result.exportData);
return export_result.resultCode;
}
KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
String16 key_name16(key_name.data(), key_name.size());
- return keystore_->del(key_name16, kDefaultUID);
+ int32_t result;
+ auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ return KeyStoreNativeReturnCode(result);
}
KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
- return keystore_->clear_uid(kDefaultUID);
+ int32_t result;
+ auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ return KeyStoreNativeReturnCode(result);
}
-KeyStoreNativeReturnCode KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
- const AuthorizationSet& input_parameters,
- AuthorizationSet* output_parameters,
- uint64_t* handle) {
+KeyStoreNativeReturnCode
+KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
+ const AuthorizationSet& input_parameters,
+ 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;
- keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_parameters.hidl_data(),
- hidl_vec<uint8_t>(), kDefaultUID, &result);
+ auto binder_result = keystore_->begin(
+ token, key_name16, (int)purpose, true /*pruneable*/,
+ android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
+ hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
if (result.resultCode.isOk()) {
*handle = getNextVirtualHandle();
active_operations_[*handle] = result.token;
@@ -275,19 +295,20 @@
return result.resultCode;
}
-KeyStoreNativeReturnCode KeystoreClientImpl::updateOperation(uint64_t handle,
- const AuthorizationSet& input_parameters,
- const std::string& input_data,
- size_t* num_input_bytes_consumed,
- AuthorizationSet* output_parameters,
- std::string* output_data) {
+KeyStoreNativeReturnCode
+KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
+ const std::string& input_data, size_t* num_input_bytes_consumed,
+ AuthorizationSet* output_parameters, std::string* output_data) {
if (active_operations_.count(handle) == 0) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
OperationResult result;
auto hidlInputData = blob2hidlVec(input_data);
- keystore_->update(active_operations_[handle], input_parameters.hidl_data(), hidlInputData,
- &result);
+ auto binder_result = keystore_->update(
+ active_operations_[handle],
+ android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
+ hidlInputData, &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
if (result.resultCode.isOk()) {
*num_input_bytes_consumed = result.inputConsumed;
@@ -300,19 +321,20 @@
return result.resultCode;
}
-KeyStoreNativeReturnCode KeystoreClientImpl::finishOperation(uint64_t handle,
- const AuthorizationSet& input_parameters,
- const std::string& signature_to_verify,
- AuthorizationSet* output_parameters,
- std::string* output_data) {
+KeyStoreNativeReturnCode
+KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
+ const std::string& signature_to_verify,
+ AuthorizationSet* output_parameters, std::string* output_data) {
if (active_operations_.count(handle) == 0) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
OperationResult result;
auto hidlSignature = blob2hidlVec(signature_to_verify);
- keystore_->finish(active_operations_[handle], input_parameters.hidl_data(),
- hidlSignature,
- hidl_vec<uint8_t>(), &result);
+ auto binder_result = keystore_->finish(
+ active_operations_[handle],
+ android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
+ (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
if (result.resultCode.isOk()) {
if (result.outParams.size()) {
@@ -329,32 +351,36 @@
if (active_operations_.count(handle) == 0) {
return ErrorCode::INVALID_OPERATION_HANDLE;
}
- auto error_code = keystore_->abort(active_operations_[handle]);
- if (error_code.isOk()) {
+ int32_t result;
+ // Current implementation does not return exceptions in android::binder::Status
+ auto binder_result = keystore_->abort(active_operations_[handle], &result);
+ if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
+ if (KeyStoreNativeReturnCode(result).isOk()) {
active_operations_.erase(handle);
}
- return error_code;
+ return KeyStoreNativeReturnCode(result);
}
bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
String16 key_name16(key_name.data(), key_name.size());
- auto error_code = keystore_->exist(key_name16, kDefaultUID);
- return error_code.isOk();
+ int32_t result;
+ auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
+ if (!binder_result.isOk()) return false; // binder error
+ return result;
}
bool KeystoreClientImpl::listKeys(const std::string& prefix,
std::vector<std::string>* key_name_list) {
String16 prefix16(prefix.data(), prefix.size());
- android::Vector<String16> matches;
- auto error_code = keystore_->list(prefix16, kDefaultUID, &matches);
- if (error_code.isOk()) {
- for (const auto& match : matches) {
- android::String8 key_name(match);
- key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
- }
- return true;
+ std::vector<::android::String16> matches;
+ auto binder_result = keystore_->list(prefix16, kDefaultUID, &matches);
+ if (!binder_result.isOk()) return false;
+
+ for (const auto& match : matches) {
+ android::String8 key_name(match);
+ key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
}
- return false;
+ return true;
}
uint64_t KeystoreClientImpl::getNextVirtualHandle() {
@@ -385,9 +411,8 @@
.Authorization(TAG_NO_AUTH_REQUIRED);
AuthorizationSet hardware_enforced_characteristics;
AuthorizationSet software_enforced_characteristics;
- auto result =
- generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
- &software_enforced_characteristics);
+ auto result = generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
+ &software_enforced_characteristics);
if (!result.isOk()) {
ALOGE("Failed to generate encryption key: %d", int32_t(result));
return false;
@@ -423,9 +448,8 @@
.Authorization(TAG_NO_AUTH_REQUIRED);
AuthorizationSet hardware_enforced_characteristics;
AuthorizationSet software_enforced_characteristics;
- auto result =
- generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
- &software_enforced_characteristics);
+ auto result = generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
+ &software_enforced_characteristics);
if (!result.isOk()) {
ALOGE("Failed to generate authentication key: %d", int32_t(result));
return false;
@@ -442,32 +466,32 @@
AuthorizationSet hardware_enforced_characteristics;
AuthorizationSet software_enforced_characteristics;
auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
- &software_enforced_characteristics);
+ &software_enforced_characteristics);
if (!result.isOk()) {
ALOGE("Failed to query encryption key: %d", int32_t(result));
return false;
}
*verified = true;
auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
- software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+ software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
ALOGW("Found encryption key with invalid algorithm.");
*verified = false;
}
auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
- software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+ software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
if (!key_size.isOk() || key_size.value() != kAESKeySize) {
ALOGW("Found encryption key with invalid size.");
*verified = false;
}
auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
- software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
+ software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
ALOGW("Found encryption key with invalid block mode.");
*verified = false;
}
auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
- software_enforced_characteristics.GetTagValue(TAG_PADDING));
+ software_enforced_characteristics.GetTagValue(TAG_PADDING));
if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
ALOGW("Found encryption key with invalid padding mode.");
*verified = false;
@@ -483,32 +507,32 @@
AuthorizationSet hardware_enforced_characteristics;
AuthorizationSet software_enforced_characteristics;
auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
- &software_enforced_characteristics);
+ &software_enforced_characteristics);
if (!result.isOk()) {
ALOGE("Failed to query authentication key: %d", int32_t(result));
return false;
}
*verified = true;
auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
- software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
- if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC){
+ software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+ if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
ALOGW("Found authentication key with invalid algorithm.");
*verified = false;
}
auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
- software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+ software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
ALOGW("Found authentication key with invalid size.");
*verified = false;
}
auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
- software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
+ software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
ALOGW("Found authentication key with invalid minimum mac size.");
*verified = false;
}
auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
- software_enforced_characteristics.GetTagValue(TAG_DIGEST));
+ software_enforced_characteristics.GetTagValue(TAG_DIGEST));
if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
ALOGW("Found authentication key with invalid digest list.");
*verified = false;
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
index 8fb7f80..cf67fa4 100644
--- a/keystore/keystore_get.cpp
+++ b/keystore/keystore_get.cpp
@@ -14,24 +14,26 @@
* limitations under the License.
*/
-#include <keystore/IKeystoreService.h>
+#include <android/security/IKeystoreService.h>
#include <binder/IServiceManager.h>
#include <keystore/keystore_get.h>
+#include <vector>
using namespace android;
using namespace keystore;
-ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
+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<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+ sp<android::security::IKeystoreService> service =
+ interface_cast<android::security::IKeystoreService>(binder);
if (service == NULL) {
return -1;
}
- hidl_vec<uint8_t> result;
+ ::std::vector<uint8_t> result;
auto ret = service->get(String16(key, keyLength), -1, &result);
if (!ret.isOk()) return -1;
@@ -41,5 +43,4 @@
memcpy(*value, &result[0], result.size());
}
return result.size();
-
}
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index 0389201..3cdf649 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -73,13 +73,13 @@
return now_date > expiration_date;
}
- bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const {
+ bool auth_token_timed_out(const HardwareAuthToken&, uint32_t) const {
// Assume the token has not timed out, because AuthTokenTable would not have returned it if
// the timeout were past. Secure hardware will also check timeouts if it supports them.
return false;
}
- bool ValidateTokenSignature(const hw_auth_token_t&) const override {
+ bool ValidateTokenSignature(const HardwareAuthToken&) const override {
// Non-secure world cannot validate token signatures because it doesn't have access to the
// signing key. Assume the token is good.
return true;
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index a739c5e..e42d5a4 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -30,6 +30,7 @@
#include "key_store_service.h"
#include "keystore.h"
#include "permissions.h"
+#include <android/security/IKeystoreService.h>
#include "legacy_keymaster_device_wrapper.h"
#include "include/keystore/keystore_hidl_support.h"
#include "include/keystore/keystore_return_types.h"
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index b1777d0..54883b9 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -27,8 +27,6 @@
#include <keystore/authorization_set.h>
#include <keystore/keystore_client.h>
-#include <keystore/IKeystoreService.h>
-
size_t readFully(int fd, uint8_t* data, size_t size) {
size_t remaining = size;
while (remaining > 0) {
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index cc89681..6d8f75d 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -1,13 +1,16 @@
// Unit test for AuthTokenTable
-// TODO: enable after fixing b/68149839
-/*
+
cc_test {
cflags: [
"-Wall",
"-Werror",
"-Wextra",
],
- srcs: ["auth_token_table_test.cpp"],
+ srcs: [
+ "auth_token_table_test.cpp",
+ "auth_token_formatting_test.cpp",
+ "gtest_main.cpp",
+ ],
name: "keystore_unit_tests",
tags: ["test"],
static_libs: [
@@ -17,4 +20,3 @@
],
shared_libs: ["libkeymaster_messages"],
}
-*/
diff --git a/keystore/tests/auth_token_formatting_test.cpp b/keystore/tests/auth_token_formatting_test.cpp
new file mode 100644
index 0000000..d6e712e
--- /dev/null
+++ b/keystore/tests/auth_token_formatting_test.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 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 <gtest/gtest.h>
+
+#include <endian.h>
+#include <keymaster/logger.h>
+#include <hidl/HidlSupport.h>
+#include <android/hardware/keymaster/3.0/types.h>
+#include <hardware/hw_auth_token.h>
+
+#include "../auth_token_table.h"
+#include <keystore/keystore_hidl_support.h>
+
+using std::vector;
+
+namespace keystore {
+namespace test {
+
+namespace {
+
+class StdoutLogger : public keymaster::Logger {
+ public:
+ StdoutLogger() { set_instance(this); }
+
+ int log_msg(LogLevel level, const char* fmt, va_list args) const {
+ int output_len = 0;
+ switch (level) {
+ case DEBUG_LVL:
+ output_len = printf("DEBUG: ");
+ break;
+ case INFO_LVL:
+ output_len = printf("INFO: ");
+ break;
+ case WARNING_LVL:
+ output_len = printf("WARNING: ");
+ break;
+ case ERROR_LVL:
+ output_len = printf("ERROR: ");
+ break;
+ case SEVERE_LVL:
+ output_len = printf("SEVERE: ");
+ break;
+ }
+
+ output_len += vprintf(fmt, args);
+ output_len += printf("\n");
+ return output_len;
+ }
+};
+
+StdoutLogger logger;
+
+}
+
+
+using android::hardware::keymaster::V3_0::HardwareAuthToken;
+using android::hardware::hidl_vec;
+using android::hardware::hidl_array;
+
+constexpr const uint8_t test_token[69] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44
+};
+
+
+constexpr const uint8_t test_hmac_data[] = {
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+ 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+ 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44 };
+
+static const HardwareAuthToken hidl_test_token_little_endian = {
+ UINT64_C(0x0807060504030201),
+ UINT64_C(0x100f0e0d0c0b0a09),
+ UINT64_C(0x1817161514131211),
+ UINT32_C(0x1c1b1a19),
+ UINT64_C(0x24232221201f1e1d),
+ hidl_array<uint8_t, 32>(test_hmac_data)
+};
+
+
+TEST(AuthenticationTokenFormattingTest, hidlVec2AuthToken) {
+ static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+ hidl_vec<uint8_t> hidl_test_token;
+ hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+ ASSERT_EQ(hidl_test_token_little_endian, hidlVec2AuthToken(hidl_test_token));
+}
+
+TEST(AuthenticationTokenFormattingTest, authToken2HidlVec) {
+ static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+ hidl_vec<uint8_t> hidl_test_token;
+ hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+ ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidl_test_token_little_endian));
+}
+
+TEST(AuthenticationTokenFormattingTest, backAndForth) {
+ static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+ hidl_vec<uint8_t> hidl_test_token;
+ hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+ ASSERT_EQ(hidl_test_token_little_endian, hidlVec2AuthToken(authToken2HidlVec(hidl_test_token_little_endian)));
+}
+
+TEST(AuthenticationTokenFormattingTest, forthAndBack) {
+ static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+ hidl_vec<uint8_t> hidl_test_token;
+ hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+ ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidlVec2AuthToken(hidl_test_token)));
+}
+
+} // namespace keymaster
+} // namespace test
diff --git a/keystore/tests/auth_token_table_test.cpp b/keystore/tests/auth_token_table_test.cpp
index 1b31cf5..5206ba2 100644
--- a/keystore/tests/auth_token_table_test.cpp
+++ b/keystore/tests/auth_token_table_test.cpp
@@ -16,21 +16,17 @@
#include <gtest/gtest.h>
-#include <keymaster/android_keymaster_utils.h>
+#include <endian.h>
#include <keymaster/logger.h>
#include "../auth_token_table.h"
using std::vector;
-inline bool operator==(const hw_auth_token_t& a, const hw_auth_token_t& b) {
- return (memcmp(&a, &b, sizeof(a)) == 0);
-}
-
-namespace keymaster {
+namespace keystore {
namespace test {
-class StdoutLogger : public Logger {
+class StdoutLogger : public keymaster::Logger {
public:
StdoutLogger() { set_instance(this); }
@@ -66,26 +62,27 @@
AuthTokenTable table;
}
-static hw_auth_token_t* make_token(uint64_t rsid, uint64_t ssid = 0, uint64_t challenge = 0,
- uint64_t timestamp = 0) {
- hw_auth_token_t* token = new hw_auth_token_t;
- token->user_id = rsid;
- token->authenticator_id = ssid;
- token->authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+static std::unique_ptr<const HardwareAuthToken> make_token(uint64_t rsid, uint64_t ssid = 0,
+ uint64_t challenge = 0,
+ uint64_t timestamp = 0) {
+ std::unique_ptr<HardwareAuthToken> token(new HardwareAuthToken);
+ token->userId = rsid;
+ token->authenticatorId = ssid;
+ token->authenticatorType = htonl(static_cast<uint32_t>(HardwareAuthenticatorType::PASSWORD));
token->challenge = challenge;
- token->timestamp = hton(timestamp);
+ token->timestamp = htonq(timestamp);
return token;
}
static AuthorizationSet make_set(uint64_t rsid, uint32_t timeout = 10000) {
AuthorizationSetBuilder builder;
builder.Authorization(TAG_USER_ID, 10)
- .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
.Authorization(TAG_USER_SECURE_ID, rsid);
// Use timeout == 0 to indicate tags that require auth per operation.
if (timeout != 0)
builder.Authorization(TAG_AUTH_TIMEOUT, timeout);
- return builder.build();
+ return builder;
}
// Tests obviously run so fast that a real-time clock with a one-second granularity rarely changes
@@ -102,26 +99,26 @@
table.AddAuthenticationToken(make_token(3, 4));
EXPECT_EQ(2U, table.size());
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
- ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(1U, found->user_id);
- EXPECT_EQ(2U, found->authenticator_id);
+ ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(1U, found->userId);
+ EXPECT_EQ(2U, found->authenticatorId);
- ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(1U, found->user_id);
- EXPECT_EQ(2U, found->authenticator_id);
+ ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(1U, found->userId);
+ EXPECT_EQ(2U, found->authenticatorId);
- ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(3U, found->user_id);
- EXPECT_EQ(4U, found->authenticator_id);
+ ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(3U, found->userId);
+ EXPECT_EQ(4U, found->authenticatorId);
- ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(3U, found->user_id);
- EXPECT_EQ(4U, found->authenticator_id);
+ ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(3U, found->userId);
+ EXPECT_EQ(4U, found->authenticatorId);
ASSERT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(5), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
}
TEST(AuthTokenTableTest, FlushTable) {
@@ -131,13 +128,13 @@
table.AddAuthenticationToken(make_token(2));
table.AddAuthenticationToken(make_token(3));
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
// All three should be in the table.
EXPECT_EQ(3U, table.size());
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
table.Clear();
EXPECT_EQ(0U, table.size());
@@ -150,36 +147,36 @@
table.AddAuthenticationToken(make_token(2));
table.AddAuthenticationToken(make_token(3));
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
// All three should be in the table.
EXPECT_EQ(3U, table.size());
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
table.AddAuthenticationToken(make_token(4));
// Oldest should be gone.
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
// Others should be there, including the new one (4). Search for it first, then the others, so
// 4 becomes the least recently used.
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
table.AddAuthenticationToken(make_token(5));
// 5 should have replaced 4.
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(4), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(5), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
table.AddAuthenticationToken(make_token(6));
table.AddAuthenticationToken(make_token(7));
@@ -187,12 +184,12 @@
// 2 and 5 should be gone
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(5), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(6), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(7), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
table.AddAuthenticationToken(make_token(8));
table.AddAuthenticationToken(make_token(9));
@@ -201,75 +198,75 @@
// Only the three most recent should be there.
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(3), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(4), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(5), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(6), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(7), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(8), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(9), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(8), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(9), KeyPurpose::SIGN, 0, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(10), KM_PURPOSE_SIGN, 0, &found));
+ table.FindAuthorization(make_set(10), KeyPurpose::SIGN, 0, &found));
}
TEST(AuthTokenTableTest, AuthenticationNotRequired) {
AuthTokenTable table;
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
EXPECT_EQ(AuthTokenTable::AUTH_NOT_REQUIRED,
table.FindAuthorization(
- AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED).build(),
- KM_PURPOSE_SIGN, 0 /* no challenge */, &found));
+ AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED),
+ KeyPurpose::SIGN, 0 /* no challenge */, &found));
}
TEST(AuthTokenTableTest, OperationHandleNotFound) {
AuthTokenTable table;
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
table.AddAuthenticationToken(make_token(1, 0, 1, 5));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
2 /* non-matching challenge */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* matching challenge */, &found));
table.MarkCompleted(1);
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* used challenge */, &found));
}
TEST(AuthTokenTableTest, OperationHandleRequired) {
AuthTokenTable table;
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
table.AddAuthenticationToken(make_token(1));
EXPECT_EQ(AuthTokenTable::OP_HANDLE_REQUIRED,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
0 /* no op handle */, &found));
}
TEST(AuthTokenTableTest, AuthSidChanged) {
AuthTokenTable table;
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
table.AddAuthenticationToken(make_token(1, 3, /* op handle */ 1));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_WRONG_SID,
- table.FindAuthorization(make_set(2, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(2, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* op handle */, &found));
}
TEST(AuthTokenTableTest, TokenExpired) {
AuthTokenTable table(5, monotonic_clock);
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
auto key_info = make_set(1, 5 /* five second timeout */);
@@ -281,17 +278,17 @@
// keymaster when the found token is passed to it.
table.AddAuthenticationToken(make_token(1, 0));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_EXPIRED,
- table.FindAuthorization(key_info, KM_PURPOSE_SIGN, 0 /* no op handle */, &found));
+ table.FindAuthorization(key_info, KeyPurpose::SIGN, 0 /* no op handle */, &found));
}
TEST(AuthTokenTableTest, MarkNonexistentEntryCompleted) {
@@ -302,15 +299,15 @@
TEST(AuthTokenTableTest, SupersededEntries) {
AuthTokenTable table;
- const hw_auth_token_t* found;
+ const HardwareAuthToken* found;
// Add two identical tokens, without challenges. The second should supersede the first, based
// on timestamp (fourth arg to make_token).
table.AddAuthenticationToken(make_token(1, 0, 0, 0));
table.AddAuthenticationToken(make_token(1, 0, 0, 1));
EXPECT_EQ(1U, table.size());
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(1U, ntoh(found->timestamp));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(1U, ntohq(found->timestamp));
// Add a third token, this with a different RSID. It should not be superseded.
table.AddAuthenticationToken(make_token(2, 0, 0, 2));
@@ -320,10 +317,10 @@
table.AddAuthenticationToken(make_token(1, 0, 0, 3));
table.AddAuthenticationToken(make_token(2, 0, 0, 4));
EXPECT_EQ(2U, table.size());
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(3U, ntoh(found->timestamp));
- EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0, &found));
- EXPECT_EQ(4U, ntoh(found->timestamp));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(3U, ntohq(found->timestamp));
+ EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+ EXPECT_EQ(4U, ntohq(found->timestamp));
// Add another, this one with a challenge value. It should supersede the old one since it is
// newer, and matches other than the challenge.
@@ -338,13 +335,13 @@
// Should be able to find each of them, by specifying their challenge, with a key that is not
// timed (timed keys don't care about challenges).
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout*/), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout*/), KeyPurpose::SIGN,
1 /* challenge */, &found));
- EXPECT_EQ(5U, ntoh(found->timestamp));
+ EXPECT_EQ(5U, ntohq(found->timestamp));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
2 /* challenge */, &found));
- EXPECT_EQ(6U, ntoh(found->timestamp));
+ EXPECT_EQ(6U, ntohq(found->timestamp));
// Add another, without a challenge, and the same timestamp as the last one. This new one
// actually could be considered already-superseded, but the table doesn't handle that case,
@@ -352,31 +349,31 @@
table.AddAuthenticationToken(make_token(1, 0, 0, 6));
EXPECT_EQ(4U, table.size());
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(6U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(6U, ntohq(found->timestamp));
// Add another without a challenge but an increased timestamp. This should supersede the
// previous challenge-free entry.
table.AddAuthenticationToken(make_token(1, 0, 0, 7));
EXPECT_EQ(4U, table.size());
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
2 /* challenge */, &found));
- EXPECT_EQ(6U, ntoh(found->timestamp));
+ EXPECT_EQ(6U, ntohq(found->timestamp));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(7U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(7U, ntohq(found->timestamp));
// Mark the entry with challenge 2 as complete. Since there's a newer challenge-free entry, the
// challenge entry will be superseded.
table.MarkCompleted(2);
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
2 /* challenge */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(7U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(7U, ntohq(found->timestamp));
// Add another SID 1 entry with a challenge. It supersedes the previous SID 1 entry with
// no challenge (timestamp 7), but not the one with challenge 1 (timestamp 5).
@@ -384,19 +381,19 @@
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* challenge */, &found));
- EXPECT_EQ(5U, ntoh(found->timestamp));
+ EXPECT_EQ(5U, ntohq(found->timestamp));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
3 /* challenge */, &found));
- EXPECT_EQ(8U, ntoh(found->timestamp));
+ EXPECT_EQ(8U, ntohq(found->timestamp));
// SID 2 entry is still there.
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(2), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(4U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(4U, ntohq(found->timestamp));
// Mark the entry with challenge 3 as complete. Since the older challenge 1 entry is
// incomplete, nothing is superseded.
@@ -404,24 +401,24 @@
EXPECT_EQ(3U, table.size());
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* challenge */, &found));
- EXPECT_EQ(5U, ntoh(found->timestamp));
+ EXPECT_EQ(5U, ntohq(found->timestamp));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(8U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(8U, ntohq(found->timestamp));
// Mark the entry with challenge 1 as complete. Since there's a newer one (with challenge 3,
// completed), the challenge 1 entry is superseded and removed.
table.MarkCompleted(1);
EXPECT_EQ(2U, table.size());
EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
- table.FindAuthorization(make_set(1, 0 /* no timeout */), KM_PURPOSE_SIGN,
+ table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
1 /* challenge */, &found));
EXPECT_EQ(AuthTokenTable::OK,
- table.FindAuthorization(make_set(1), KM_PURPOSE_SIGN, 0 /* challenge */, &found));
- EXPECT_EQ(8U, ntoh(found->timestamp));
+ table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
+ EXPECT_EQ(8U, ntohq(found->timestamp));
}
} // namespace keymaster
diff --git a/softkeymaster/Android.bp b/softkeymaster/Android.bp
deleted file mode 100644
index 3d27ecb..0000000
--- a/softkeymaster/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-cc_defaults {
- name: "softkeymaster_defaults",
-
- cflags: [
- "-Wall",
- "-Werror",
- "-fvisibility=hidden",
- ],
-}
-
-cc_library_shared {
- name: "keystore.default",
- defaults: ["softkeymaster_defaults"],
-
- relative_install_path: "hw",
- srcs: ["module.cpp"],
- include_dirs: ["system/security/keystore"],
- shared_libs: [
- "libcrypto",
- "libkeystore_binder",
- "liblog",
- "libsoftkeymaster",
- ],
-}
-
-cc_library_shared {
- name: "libsoftkeymaster",
- defaults: ["softkeymaster_defaults"],
-
- srcs: ["keymaster_openssl.cpp"],
- include_dirs: ["system/security/keystore"],
- local_include_dirs: [],
- shared_libs: [
- "libcrypto",
- "libkeystore_binder",
- "liblog",
- ],
-
- export_include_dirs: ["include"],
-}
diff --git a/softkeymaster/include/keymaster/softkeymaster.h b/softkeymaster/include/keymaster/softkeymaster.h
deleted file mode 100644
index e86ba3d..0000000
--- a/softkeymaster/include/keymaster/softkeymaster.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2013 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 <hardware/keymaster0.h>
-
-#ifndef SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
-#define SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
-
-int openssl_generate_keypair(const keymaster0_device_t* dev, const keymaster_keypair_t key_type,
- const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength);
-
-int openssl_import_keypair(const keymaster0_device_t* dev, const uint8_t* key,
- const size_t key_length, uint8_t** key_blob, size_t* key_blob_length);
-
-int openssl_get_keypair_public(const struct keymaster0_device* dev, const uint8_t* key_blob,
- const size_t key_blob_length, uint8_t** x509_data,
- size_t* x509_data_length);
-
-int openssl_sign_data(const keymaster0_device_t* dev, const void* params, const uint8_t* keyBlob,
- const size_t keyBlobLength, const uint8_t* data, const size_t dataLength,
- uint8_t** signedData, size_t* signedDataLength);
-
-int openssl_verify_data(const keymaster0_device_t* dev, const void* params, const uint8_t* keyBlob,
- const size_t keyBlobLength, const uint8_t* signedData,
- const size_t signedDataLength, const uint8_t* signature,
- const size_t signatureLength);
-
-int openssl_open(const hw_module_t* module, const char* name, hw_device_t** device);
-
-extern struct keystore_module softkeymaster_module;
-
-#endif // SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
deleted file mode 100644
index f4d55bd..0000000
--- a/softkeymaster/keymaster_openssl.cpp
+++ /dev/null
@@ -1,785 +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.
- */
-#include <errno.h>
-#include <string.h>
-#include <stdint.h>
-
-#include <keystore/keystore.h>
-#include <keymaster/softkeymaster.h>
-
-#include <hardware/hardware.h>
-#include <hardware/keymaster0.h>
-
-#include <openssl/evp.h>
-#include <openssl/bio.h>
-#include <openssl/rsa.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-
-#include <memory>
-
-// For debugging
-// #define LOG_NDEBUG 0
-
-#define LOG_TAG "OpenSSLKeyMaster"
-#include <cutils/log.h>
-
-struct BIGNUM_Delete {
- void operator()(BIGNUM* p) const { BN_free(p); }
-};
-typedef std::unique_ptr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
-
-struct EVP_PKEY_Delete {
- void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
-};
-typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-struct PKCS8_PRIV_KEY_INFO_Delete {
- void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
-};
-typedef std::unique_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
-
-struct DSA_Delete {
- void operator()(DSA* p) const { DSA_free(p); }
-};
-typedef std::unique_ptr<DSA, DSA_Delete> Unique_DSA;
-
-struct EC_KEY_Delete {
- void operator()(EC_KEY* p) const { EC_KEY_free(p); }
-};
-typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
-
-struct EC_GROUP_Delete {
- void operator()(EC_GROUP* p) const { EC_GROUP_free(p); }
-};
-typedef std::unique_ptr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
-
-struct RSA_Delete {
- void operator()(RSA* p) const { RSA_free(p); }
-};
-typedef std::unique_ptr<RSA, RSA_Delete> Unique_RSA;
-
-struct Malloc_Free {
- void operator()(void* p) const { free(p); }
-};
-
-typedef std::unique_ptr<keymaster0_device_t> Unique_keymaster_device_t;
-
-/**
- * Many OpenSSL APIs take ownership of an argument on success but
- * don't free 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().
- */
-template <typename T, typename Delete_T>
-inline void release_because_ownership_transferred(std::unique_ptr<T, Delete_T>& p) {
- T* val __attribute__((unused)) = p.release();
-}
-
-/*
- * Checks this thread's OpenSSL error queue and logs if
- * necessary.
- */
-static void logOpenSSLError(const char* location) {
- int error = ERR_get_error();
-
- if (error != 0) {
- char message[256];
- ERR_error_string_n(error, message, sizeof(message));
- ALOGE("OpenSSL error in %s %d: %s", location, error, message);
- }
-
- ERR_clear_error();
- ERR_remove_thread_state(NULL);
-}
-
-static int wrap_key(EVP_PKEY* pkey, int type, uint8_t** keyBlob, size_t* keyBlobLength) {
- /*
- * Find the length of each size. Public key is not needed anymore
- * but must be kept for alignment purposes.
- */
- int publicLen = 0;
- int privateLen = i2d_PrivateKey(pkey, NULL);
-
- if (privateLen <= 0) {
- ALOGE("private key size was too big");
- return -1;
- }
-
- /* int type + int size + private key data + int size + public key data */
- *keyBlobLength = get_softkey_header_size() + sizeof(type) + sizeof(publicLen) + privateLen +
- sizeof(privateLen) + publicLen;
-
- // derData will be returned to the caller, so allocate it with malloc.
- std::unique_ptr<unsigned char, Malloc_Free> derData(
- static_cast<unsigned char*>(malloc(*keyBlobLength)));
- if (derData.get() == NULL) {
- ALOGE("could not allocate memory for key blob");
- return -1;
- }
- unsigned char* p = derData.get();
-
- /* Write the magic value for software keys. */
- p = add_softkey_header(p, *keyBlobLength);
-
- /* Write key type to allocated buffer */
- for (int i = sizeof(type) - 1; i >= 0; i--) {
- *p++ = (type >> (8 * i)) & 0xFF;
- }
-
- /* Write public key to allocated buffer */
- for (int i = sizeof(publicLen) - 1; i >= 0; i--) {
- *p++ = (publicLen >> (8 * i)) & 0xFF;
- }
-
- /* Write private key to allocated buffer */
- for (int i = sizeof(privateLen) - 1; i >= 0; i--) {
- *p++ = (privateLen >> (8 * i)) & 0xFF;
- }
- if (i2d_PrivateKey(pkey, &p) != privateLen) {
- logOpenSSLError("wrap_key");
- return -1;
- }
-
- *keyBlob = derData.release();
-
- return 0;
-}
-
-static EVP_PKEY* unwrap_key(const uint8_t* keyBlob, const size_t keyBlobLength) {
- long publicLen = 0;
- long privateLen = 0;
- const uint8_t* p = keyBlob;
- const uint8_t* const end = keyBlob + keyBlobLength;
-
- if (keyBlob == NULL) {
- ALOGE("supplied key blob was NULL");
- return NULL;
- }
-
- int type = 0;
- if (keyBlobLength < (get_softkey_header_size() + sizeof(type) + sizeof(publicLen) + 1 +
- sizeof(privateLen) + 1)) {
- ALOGE("key blob appears to be truncated");
- return NULL;
- }
-
- if (!is_softkey(p, keyBlobLength)) {
- ALOGE("cannot read key; it was not made by this keymaster");
- return NULL;
- }
- p += get_softkey_header_size();
-
- for (size_t i = 0; i < sizeof(type); i++) {
- type = (type << 8) | *p++;
- }
-
- for (size_t i = 0; i < sizeof(type); i++) {
- publicLen = (publicLen << 8) | *p++;
- }
- if (p + publicLen > end) {
- ALOGE("public key length encoding error: size=%ld, end=%td", publicLen, end - p);
- return NULL;
- }
-
- p += publicLen;
- if (end - p < 2) {
- ALOGE("private key truncated");
- return NULL;
- }
- for (size_t i = 0; i < sizeof(type); i++) {
- privateLen = (privateLen << 8) | *p++;
- }
- if (p + privateLen > end) {
- ALOGE("private key length encoding error: size=%ld, end=%td", privateLen, end - p);
- return NULL;
- }
-
- Unique_EVP_PKEY pkey(d2i_PrivateKey(type, nullptr, &p, privateLen));
- if (pkey.get() == NULL) {
- logOpenSSLError("unwrap_key");
- return NULL;
- }
-
- return pkey.release();
-}
-
-static int generate_dsa_keypair(EVP_PKEY* pkey, const keymaster_dsa_keygen_params_t* dsa_params) {
- if (dsa_params->key_size < 512) {
- ALOGI("Requested DSA key size is too small (<512)");
- return -1;
- }
-
- Unique_DSA dsa(DSA_new());
-
- if (dsa_params->generator_len == 0 || dsa_params->prime_p_len == 0 ||
- dsa_params->prime_q_len == 0 || dsa_params->generator == NULL ||
- dsa_params->prime_p == NULL || dsa_params->prime_q == NULL) {
- if (DSA_generate_parameters_ex(dsa.get(), dsa_params->key_size, NULL, 0, NULL, NULL,
- NULL) != 1) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
- } else {
- dsa->g = BN_bin2bn(dsa_params->generator, dsa_params->generator_len, NULL);
- if (dsa->g == NULL) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
-
- dsa->p = BN_bin2bn(dsa_params->prime_p, dsa_params->prime_p_len, NULL);
- if (dsa->p == NULL) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
-
- dsa->q = BN_bin2bn(dsa_params->prime_q, dsa_params->prime_q_len, NULL);
- if (dsa->q == NULL) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
- }
-
- if (DSA_generate_key(dsa.get()) != 1) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
-
- if (EVP_PKEY_assign_DSA(pkey, dsa.get()) == 0) {
- logOpenSSLError("generate_dsa_keypair");
- return -1;
- }
- release_because_ownership_transferred(dsa);
-
- return 0;
-}
-
-static int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params) {
- Unique_EC_GROUP group;
- switch (ec_params->field_size) {
- case 224:
- group.reset(EC_GROUP_new_by_curve_name(NID_secp224r1));
- break;
- case 256:
- group.reset(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
- break;
- case 384:
- group.reset(EC_GROUP_new_by_curve_name(NID_secp384r1));
- break;
- case 521:
- group.reset(EC_GROUP_new_by_curve_name(NID_secp521r1));
- break;
- default:
- break;
- }
-
- if (group.get() == NULL) {
- logOpenSSLError("generate_ec_keypair");
- return -1;
- }
-
-#if !defined(OPENSSL_IS_BORINGSSL)
- EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
- EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
-#endif
-
- /* initialize EC key */
- Unique_EC_KEY eckey(EC_KEY_new());
- if (eckey.get() == NULL) {
- logOpenSSLError("generate_ec_keypair");
- return -1;
- }
-
- if (EC_KEY_set_group(eckey.get(), group.get()) != 1) {
- logOpenSSLError("generate_ec_keypair");
- return -1;
- }
-
- if (EC_KEY_generate_key(eckey.get()) != 1 || EC_KEY_check_key(eckey.get()) < 0) {
- logOpenSSLError("generate_ec_keypair");
- return -1;
- }
-
- if (EVP_PKEY_assign_EC_KEY(pkey, eckey.get()) == 0) {
- logOpenSSLError("generate_ec_keypair");
- return -1;
- }
- release_because_ownership_transferred(eckey);
-
- return 0;
-}
-
-static int generate_rsa_keypair(EVP_PKEY* pkey, const keymaster_rsa_keygen_params_t* rsa_params) {
- Unique_BIGNUM bn(BN_new());
- if (bn.get() == NULL) {
- logOpenSSLError("generate_rsa_keypair");
- return -1;
- }
-
- if (BN_set_word(bn.get(), rsa_params->public_exponent) == 0) {
- logOpenSSLError("generate_rsa_keypair");
- return -1;
- }
-
- /* initialize RSA */
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- logOpenSSLError("generate_rsa_keypair");
- return -1;
- }
-
- if (!RSA_generate_key_ex(rsa.get(), rsa_params->modulus_size, bn.get(), NULL) ||
- RSA_check_key(rsa.get()) < 0) {
- logOpenSSLError("generate_rsa_keypair");
- return -1;
- }
-
- if (EVP_PKEY_assign_RSA(pkey, rsa.get()) == 0) {
- logOpenSSLError("generate_rsa_keypair");
- return -1;
- }
- release_because_ownership_transferred(rsa);
-
- return 0;
-}
-
-__attribute__((visibility("default"))) int openssl_generate_keypair(
- const keymaster0_device_t*, const keymaster_keypair_t key_type, const void* key_params,
- uint8_t** keyBlob, size_t* keyBlobLength) {
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- logOpenSSLError("openssl_generate_keypair");
- return -1;
- }
-
- if (key_params == NULL) {
- ALOGW("key_params == null");
- return -1;
- } else if (key_type == TYPE_DSA) {
- const keymaster_dsa_keygen_params_t* dsa_params =
- (const keymaster_dsa_keygen_params_t*)key_params;
- generate_dsa_keypair(pkey.get(), dsa_params);
- } else if (key_type == TYPE_EC) {
- const keymaster_ec_keygen_params_t* ec_params =
- (const keymaster_ec_keygen_params_t*)key_params;
- generate_ec_keypair(pkey.get(), ec_params);
- } else if (key_type == TYPE_RSA) {
- const keymaster_rsa_keygen_params_t* rsa_params =
- (const keymaster_rsa_keygen_params_t*)key_params;
- generate_rsa_keypair(pkey.get(), rsa_params);
- } else {
- ALOGW("Unsupported key type %d", key_type);
- return -1;
- }
-
- if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), keyBlob, keyBlobLength)) {
- return -1;
- }
-
- return 0;
-}
-
-__attribute__((visibility("default"))) int openssl_import_keypair(const keymaster0_device_t*,
- const uint8_t* key,
- const size_t key_length,
- uint8_t** key_blob,
- size_t* key_blob_length) {
- if (key == NULL) {
- ALOGW("input key == NULL");
- return -1;
- } else if (key_blob == NULL || key_blob_length == NULL) {
- ALOGW("output key blob or length == NULL");
- return -1;
- }
-
- Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
- if (pkcs8.get() == NULL) {
- logOpenSSLError("openssl_import_keypair");
- return -1;
- }
-
- /* assign to EVP */
- Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
- if (pkey.get() == NULL) {
- logOpenSSLError("openssl_import_keypair");
- return -1;
- }
-
- if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
- return -1;
- }
-
- return 0;
-}
-
-__attribute__((visibility("default"))) int openssl_get_keypair_public(const keymaster0_device_t*,
- const uint8_t* key_blob,
- const size_t key_blob_length,
- uint8_t** x509_data,
- size_t* x509_data_length) {
- if (x509_data == NULL || x509_data_length == NULL) {
- ALOGW("output public key buffer == NULL");
- return -1;
- }
-
- Unique_EVP_PKEY pkey(unwrap_key(key_blob, key_blob_length));
- if (pkey.get() == NULL) {
- return -1;
- }
-
- int len = i2d_PUBKEY(pkey.get(), NULL);
- if (len <= 0) {
- logOpenSSLError("openssl_get_keypair_public");
- return -1;
- }
-
- std::unique_ptr<uint8_t, Malloc_Free> key(static_cast<uint8_t*>(malloc(len)));
- if (key.get() == NULL) {
- ALOGE("Could not allocate memory for public key data");
- return -1;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
- if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
- logOpenSSLError("openssl_get_keypair_public");
- return -1;
- }
-
- ALOGV("Length of x509 data is %d", len);
- *x509_data_length = len;
- *x509_data = key.release();
-
- return 0;
-}
-
-static int sign_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params, const uint8_t* data,
- const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- }
-
- Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
- if (dsa.get() == NULL) {
- logOpenSSLError("openssl_sign_dsa");
- return -1;
- }
-
- unsigned int dsaSize = DSA_size(dsa.get());
- std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
- if (signedDataPtr.get() == NULL) {
- logOpenSSLError("openssl_sign_dsa");
- return -1;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
- if (DSA_sign(0, data, dataLength, tmp, &dsaSize, dsa.get()) <= 0) {
- logOpenSSLError("openssl_sign_dsa");
- return -1;
- }
-
- *signedDataLength = dsaSize;
- *signedData = signedDataPtr.release();
-
- return 0;
-}
-
-static int sign_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params, const uint8_t* data,
- const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- }
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- logOpenSSLError("openssl_sign_ec");
- return -1;
- }
-
- unsigned int ecdsaSize = ECDSA_size(eckey.get());
- std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
- if (signedDataPtr.get() == NULL) {
- logOpenSSLError("openssl_sign_ec");
- return -1;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
- if (ECDSA_sign(0, data, dataLength, tmp, &ecdsaSize, eckey.get()) <= 0) {
- logOpenSSLError("openssl_sign_ec");
- return -1;
- }
-
- *signedDataLength = ecdsaSize;
- *signedData = signedDataPtr.release();
-
- return 0;
-}
-
-static int sign_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params, const uint8_t* data,
- const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- } else if (sign_params->padding_type != PADDING_NONE) {
- ALOGW("Cannot handle padding type %d", sign_params->padding_type);
- return -1;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- logOpenSSLError("openssl_sign_rsa");
- return -1;
- }
-
- std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
- if (signedDataPtr.get() == NULL) {
- logOpenSSLError("openssl_sign_rsa");
- return -1;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
- if (RSA_private_encrypt(dataLength, data, tmp, rsa.get(), RSA_NO_PADDING) <= 0) {
- logOpenSSLError("openssl_sign_rsa");
- return -1;
- }
-
- *signedDataLength = dataLength;
- *signedData = signedDataPtr.release();
-
- return 0;
-}
-
-__attribute__((visibility("default"))) int openssl_sign_data(
- const keymaster0_device_t*, const void* params, const uint8_t* keyBlob,
- const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData,
- size_t* signedDataLength) {
- if (data == NULL) {
- ALOGW("input data to sign == NULL");
- return -1;
- } else if (signedData == NULL || signedDataLength == NULL) {
- ALOGW("output signature buffer == NULL");
- return -1;
- }
-
- Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength));
- if (pkey.get() == NULL) {
- return -1;
- }
-
- int type = EVP_PKEY_type(pkey->type);
- if (type == EVP_PKEY_DSA) {
- const keymaster_dsa_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_dsa_sign_params_t*>(params);
- return sign_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params), data,
- dataLength, signedData, signedDataLength);
- } else if (type == EVP_PKEY_EC) {
- const keymaster_ec_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_ec_sign_params_t*>(params);
- return sign_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params), data,
- dataLength, signedData, signedDataLength);
- } else if (type == EVP_PKEY_RSA) {
- const keymaster_rsa_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_rsa_sign_params_t*>(params);
- return sign_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params), data,
- dataLength, signedData, signedDataLength);
- } else {
- ALOGW("Unsupported key type");
- return -1;
- }
-}
-
-static int verify_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params,
- const uint8_t* signedData, const size_t signedDataLength,
- const uint8_t* signature, const size_t signatureLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- }
-
- Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
- if (dsa.get() == NULL) {
- logOpenSSLError("openssl_verify_dsa");
- return -1;
- }
-
- if (DSA_verify(0, signedData, signedDataLength, signature, signatureLength, dsa.get()) <= 0) {
- logOpenSSLError("openssl_verify_dsa");
- return -1;
- }
-
- return 0;
-}
-
-static int verify_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params,
- const uint8_t* signedData, const size_t signedDataLength,
- const uint8_t* signature, const size_t signatureLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- }
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- logOpenSSLError("openssl_verify_ec");
- return -1;
- }
-
- if (ECDSA_verify(0, signedData, signedDataLength, signature, signatureLength, eckey.get()) <=
- 0) {
- logOpenSSLError("openssl_verify_ec");
- return -1;
- }
-
- return 0;
-}
-
-static int verify_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params,
- const uint8_t* signedData, const size_t signedDataLength,
- const uint8_t* signature, const size_t signatureLength) {
- if (sign_params->digest_type != DIGEST_NONE) {
- ALOGW("Cannot handle digest type %d", sign_params->digest_type);
- return -1;
- } else if (sign_params->padding_type != PADDING_NONE) {
- ALOGW("Cannot handle padding type %d", sign_params->padding_type);
- return -1;
- } else if (signatureLength != signedDataLength) {
- ALOGW("signed data length must be signature length");
- return -1;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- logOpenSSLError("openssl_verify_data");
- return -1;
- }
-
- std::unique_ptr<uint8_t[]> dataPtr(new uint8_t[signedDataLength]);
- if (dataPtr.get() == NULL) {
- logOpenSSLError("openssl_verify_data");
- return -1;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(dataPtr.get());
- if (!RSA_public_decrypt(signatureLength, signature, tmp, rsa.get(), RSA_NO_PADDING)) {
- logOpenSSLError("openssl_verify_data");
- return -1;
- }
-
- int result = 0;
- for (size_t i = 0; i < signedDataLength; i++) {
- result |= tmp[i] ^ signedData[i];
- }
-
- return result == 0 ? 0 : -1;
-}
-
-__attribute__((visibility("default"))) int openssl_verify_data(
- const keymaster0_device_t*, const void* params, const uint8_t* keyBlob,
- const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength,
- const uint8_t* signature, const size_t signatureLength) {
- if (signedData == NULL || signature == NULL) {
- ALOGW("data or signature buffers == NULL");
- return -1;
- }
-
- Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength));
- if (pkey.get() == NULL) {
- return -1;
- }
-
- int type = EVP_PKEY_type(pkey->type);
- if (type == EVP_PKEY_DSA) {
- const keymaster_dsa_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_dsa_sign_params_t*>(params);
- return verify_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params),
- signedData, signedDataLength, signature, signatureLength);
- } else if (type == EVP_PKEY_RSA) {
- const keymaster_rsa_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_rsa_sign_params_t*>(params);
- return verify_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params),
- signedData, signedDataLength, signature, signatureLength);
- } else if (type == EVP_PKEY_EC) {
- const keymaster_ec_sign_params_t* sign_params =
- reinterpret_cast<const keymaster_ec_sign_params_t*>(params);
- return verify_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params),
- signedData, signedDataLength, signature, signatureLength);
- } else {
- ALOGW("Unsupported key type %d", type);
- return -1;
- }
-}
-
-/* Close an opened OpenSSL instance */
-static int openssl_close(hw_device_t* dev) {
- delete dev;
- return 0;
-}
-
-/*
- * Generic device handling
- */
-__attribute__((visibility("default"))) int openssl_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
- return -EINVAL;
-
- Unique_keymaster_device_t dev(new keymaster0_device_t);
- if (dev.get() == NULL)
- return -ENOMEM;
-
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 1;
- dev->common.module = (struct hw_module_t*)module;
- dev->common.close = openssl_close;
-
- dev->flags = KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE | KEYMASTER_SUPPORTS_DSA |
- KEYMASTER_SUPPORTS_EC;
-
- dev->generate_keypair = openssl_generate_keypair;
- dev->import_keypair = openssl_import_keypair;
- dev->get_keypair_public = openssl_get_keypair_public;
- dev->delete_keypair = NULL;
- dev->delete_all = NULL;
- dev->sign_data = openssl_sign_data;
- dev->verify_data = openssl_verify_data;
-
- ERR_load_crypto_strings();
- ERR_load_BIO_strings();
-
- *device = reinterpret_cast<hw_device_t*>(dev.release());
-
- return 0;
-}
-
-static struct hw_module_methods_t keystore_module_methods = {
- .open = openssl_open,
-};
-
-struct keystore_module softkeymaster_module __attribute__((visibility("default"))) = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = KEYSTORE_HARDWARE_MODULE_ID,
- .name = "Keymaster OpenSSL HAL",
- .author = "The Android Open Source Project",
- .methods = &keystore_module_methods,
- .dso = 0,
- .reserved = {},
- },
-};
diff --git a/softkeymaster/module.cpp b/softkeymaster/module.cpp
deleted file mode 100644
index 0dcbadd..0000000
--- a/softkeymaster/module.cpp
+++ /dev/null
@@ -1,24 +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.
- */
-#include <keymaster/softkeymaster.h>
-
-#include <keystore/keystore.h>
-
-#include <hardware/hardware.h>
-#include <hardware/keymaster0.h>
-
-struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default")))
- = softkeymaster_module;