/* ** ** 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()); } KeyStoreServiceReturnCode 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 ResponseCode::SYSTEM_ERROR; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("grant() caught exception %d\n", err); return ResponseCode::SYSTEM_ERROR; } return ResponseCode(reply.readInt32()); } 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(); int32_t ret = grant(name, granteeUid); reply->writeNoException(); reply->writeInt32(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