107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*
207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root**
307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** Copyright 2008, The Android Open Source Project
407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root**
507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** Licensed under the Apache License, Version 2.0 (the "License");
607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** you may not use this file except in compliance with the License.
707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** You may obtain a copy of the License at
807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root**
907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root**     http://www.apache.org/licenses/LICENSE-2.0
1007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root**
1107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** Unless required by applicable law or agreed to in writing, software
1207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** distributed under the License is distributed on an "AS IS" BASIS,
1307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** See the License for the specific language governing permissions and
1507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root** limitations under the License.
1607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root*/
1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <stdint.h>
199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker#include <sys/limits.h>
2007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <sys/types.h>
2107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "KeystoreService"
2307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <utils/Log.h>
2407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/Parcel.h>
2607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h>
2707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h>
2807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h>
3007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
3107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android {
3207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
3377d71ca20c30a5e7ecfa20980ade9b90cc7ca65cShawn Willdenconst ssize_t MAX_GENERATE_ARGS = 3;
349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakerstatic keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
3577d71ca20c30a5e7ecfa20980ade9b90cc7ca65cShawn Willden
3696427baf0094d50047049d329b0779c3c910402cKenny RootKeystoreArg::KeystoreArg(const void* data, size_t len)
3796427baf0094d50047049d329b0779c3c910402cKenny Root    : mData(data), mSize(len) {
3896427baf0094d50047049d329b0779c3c910402cKenny Root}
3996427baf0094d50047049d329b0779c3c910402cKenny Root
4096427baf0094d50047049d329b0779c3c910402cKenny RootKeystoreArg::~KeystoreArg() {
4196427baf0094d50047049d329b0779c3c910402cKenny Root}
4296427baf0094d50047049d329b0779c3c910402cKenny Root
4396427baf0094d50047049d329b0779c3c910402cKenny Rootconst void *KeystoreArg::data() const {
4496427baf0094d50047049d329b0779c3c910402cKenny Root    return mData;
4596427baf0094d50047049d329b0779c3c910402cKenny Root}
4696427baf0094d50047049d329b0779c3c910402cKenny Root
4796427baf0094d50047049d329b0779c3c910402cKenny Rootsize_t KeystoreArg::size() const {
4896427baf0094d50047049d329b0779c3c910402cKenny Root    return mSize;
4996427baf0094d50047049d329b0779c3c910402cKenny Root}
5096427baf0094d50047049d329b0779c3c910402cKenny Root
51c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad BrubakerOperationResult::OperationResult() : resultCode(0), token(), handle(0), inputConsumed(0),
529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    data(NULL), dataLength(0) {
539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerOperationResult::~OperationResult() {
569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid OperationResult::readFromParcel(const Parcel& in) {
599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    resultCode = in.readInt32();
609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    token = in.readStrongBinder();
61c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad Brubaker    handle = static_cast<keymaster_operation_handle_t>(in.readInt64());
629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    inputConsumed = in.readInt32();
639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    ssize_t length = in.readInt32();
649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    dataLength = 0;
659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (length > 0) {
669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        const void* buf = in.readInplace(length);
679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (buf) {
689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.get()) {
709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                memcpy(data.get(), buf, length);
719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                dataLength = (size_t) length;
729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            } else {
739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                ALOGE("Failed to allocate OperationResult buffer");
749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        } else {
769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to readInplace OperationResult data");
779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
7957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker    outParams.readFromParcel(in);
809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid OperationResult::writeToParcel(Parcel* out) const {
839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(resultCode);
849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeStrongBinder(token);
85c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad Brubaker    out->writeInt64(handle);
869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(inputConsumed);
879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(dataLength);
889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (dataLength && data) {
899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        void* buf = out->writeInplace(dataLength);
909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (buf) {
919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            memcpy(buf, data.get(), dataLength);
929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        } else {
939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to writeInplace OperationResult data.");
949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
9657e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker    outParams.writeToParcel(out);
979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
1009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerExportResult::~ExportResult() {
1039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid ExportResult::readFromParcel(const Parcel& in) {
1069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    resultCode = in.readInt32();
1079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    ssize_t length = in.readInt32();
1089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    dataLength = 0;
1099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (length > 0) {
1109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        const void* buf = in.readInplace(length);
1119899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (buf) {
1129899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
1139899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (exportData.get()) {
1149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                memcpy(exportData.get(), buf, length);
1159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                dataLength = (size_t) length;
1169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            } else {
1179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                ALOGE("Failed to allocate ExportData buffer");
1189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
1199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        } else {
1209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to readInplace ExportData data");
1219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
1229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
1239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid ExportResult::writeToParcel(Parcel* out) const {
1269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(resultCode);
1279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(dataLength);
1289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (exportData && dataLength) {
1299899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        void* buf = out->writeInplace(dataLength);
1309899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (buf) {
1319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            memcpy(buf, exportData.get(), dataLength);
1329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        } else {
1339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to writeInplace ExportResult data.");
1349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
1359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
1369899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerKeymasterArguments::KeymasterArguments() {
1399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerKeymasterArguments::~KeymasterArguments() {
1429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_free_param_values(params.data(), params.size());
1439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid KeymasterArguments::readFromParcel(const Parcel& in) {
1469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    ssize_t length = in.readInt32();
1479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    size_t ulength = (size_t) length;
1489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (length < 0) {
1499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        ulength = 0;
1509899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
1519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_free_param_values(params.data(), params.size());
1529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    params.clear();
1539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    for(size_t i = 0; i < ulength; i++) {
1549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        keymaster_key_param_t param;
1559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (!readKeymasterArgumentFromParcel(in, &param)) {
1569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Error reading keymaster argument from parcel");
1579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
1589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
1599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.push_back(param);
1609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
1619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid KeymasterArguments::writeToParcel(Parcel* out) const {
1649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    out->writeInt32(params.size());
1659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    for (auto param : params) {
1669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        out->writeInt32(1);
1679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        writeKeymasterArgumentToParcel(param, out);
1689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
1699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerKeyCharacteristics::KeyCharacteristics() {
1729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    memset((void*) &characteristics, 0, sizeof(characteristics));
1739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad BrubakerKeyCharacteristics::~KeyCharacteristics() {
1769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_free_characteristics(&characteristics);
1779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid KeyCharacteristics::readFromParcel(const Parcel& in) {
1809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    size_t length = 0;
1819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_key_param_t* params = readParamList(in, &length);
1829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    characteristics.sw_enforced.params = params;
1839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    characteristics.sw_enforced.length = length;
1849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    params = readParamList(in, &length);
1869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    characteristics.hw_enforced.params = params;
1879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    characteristics.hw_enforced.length = length;
1889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
1899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
1909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid KeyCharacteristics::writeToParcel(Parcel* out) const {
1919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (characteristics.sw_enforced.params) {
1929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        out->writeInt32(characteristics.sw_enforced.length);
1939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
1949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(1);
1959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
1969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
1979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    } else {
1989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        out->writeInt32(0);
1999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
2009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (characteristics.hw_enforced.params) {
2019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        out->writeInt32(characteristics.hw_enforced.length);
2029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
2039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(1);
2049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
2059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
2069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    } else {
2079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        out->writeInt32(0);
2089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
2099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
2109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
21150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn WilldenKeymasterCertificateChain::KeymasterCertificateChain() {
21250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    memset(&chain, 0, sizeof(chain));
21350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden}
21450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
21550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn WilldenKeymasterCertificateChain::~KeymasterCertificateChain() {
21650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    keymaster_free_cert_chain(&chain);
21750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden}
21850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
21950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willdenstatic bool readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
22050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    if (in.readInt32() != 1) {
22150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        return false;
22250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
22350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
22450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    ssize_t length = in.readInt32();
22550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    if (length <= 0) {
22650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        return false;
22750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
22850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
229067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    blob->data = reinterpret_cast<const uint8_t*>(malloc(length));
230067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    if (!blob->data)
231067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden        return false;
232067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
233067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    const void* buf = in.readInplace(length);
234067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    if (!buf)
235067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden        return false;
236067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
237067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    blob->data_length = static_cast<size_t>(length);
238067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    memcpy(const_cast<uint8_t*>(blob->data), buf, length);
239067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
24050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    return true;
24150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden}
24250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
24350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willdenvoid KeymasterCertificateChain::readFromParcel(const Parcel& in) {
244067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    keymaster_free_cert_chain(&chain);
245067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
24650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    ssize_t count = in.readInt32();
24750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    size_t ucount = count;
248067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    if (count <= 0) {
249067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden        return;
25050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
251067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
252067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    chain.entries = reinterpret_cast<keymaster_blob_t*>(malloc(sizeof(keymaster_blob_t) * ucount));
253067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    if (!chain.entries) {
254067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden        ALOGE("Error allocating memory for certificate chain");
255067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden        return;
256067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden    }
257067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden
25850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    memset(chain.entries, 0, sizeof(keymaster_blob_t) * ucount);
25950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    for (size_t i = 0; i < ucount; ++i) {
26050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (!readKeymasterBlob(in, &chain.entries[i])) {
261067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden            ALOGE("Error reading certificate from parcel");
26250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            keymaster_free_cert_chain(&chain);
26350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            return;
26450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        }
26550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
26650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden}
26750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
26850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willdenvoid KeymasterCertificateChain::writeToParcel(Parcel* out) const {
26950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    out->writeInt32(chain.entry_count);
27050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    for (size_t i = 0; i < chain.entry_count; ++i) {
27150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (chain.entries[i].data) {
27250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            out->writeInt32(chain.entries[i].data_length);
27350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            void* buf = out->writeInplace(chain.entries[i].data_length);
27450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            if (buf) {
27550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden                memcpy(buf, chain.entries[i].data, chain.entries[i].data_length);
27650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            } else {
27750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden                ALOGE("Failed to writeInplace keymaster cert chain entry");
27850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            }
27950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        } else {
28050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            out->writeInt32(0); // Tell Java side this object is NULL.
28150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            ALOGE("Found NULL certificate chain entry");
28250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        }
28350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
28450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden}
28550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
2869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakervoid writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
2879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    switch (keymaster_tag_get_type(param.tag)) {
2889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_ENUM:
2899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_ENUM_REP: {
2909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
2919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.enumerated);
2929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
2939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
2940ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_UINT:
2950ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_UINT_REP: {
2969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
2979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.integer);
2989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
2999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3000ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_ULONG:
3010ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_ULONG_REP: {
3029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
3039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt64(param.long_integer);
3049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_DATE: {
3079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
3089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt64(param.date_time);
3099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3119899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BOOL: {
3129899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
3139899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BIGNUM:
3169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BYTES: {
3179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.tag);
3189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            out->writeInt32(param.blob.data_length);
3199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            void* buf = out->writeInplace(param.blob.data_length);
3209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (buf) {
3219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                memcpy(buf, param.blob.data, param.blob.data_length);
3229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            } else {
3239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                ALOGE("Failed to writeInplace keymaster blob param");
3249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
3259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        default: {
3289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
3299899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3309899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
3319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
3329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
3339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
3349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakerbool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
3359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (in.readInt32() == 0) {
3369899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return false;
3379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
3389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
3399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    switch (keymaster_tag_get_type(tag)) {
3409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_ENUM:
3419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_ENUM_REP: {
3429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            uint32_t value = in.readInt32();
3439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_enum(tag, value);
3449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3460ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_UINT:
3470ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_UINT_REP: {
3489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            uint32_t value = in.readInt32();
3499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_int(tag, value);
3509899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3520ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_ULONG:
3530ebf13dbf975028735a8afc42e39c6ea47cec704Shawn Willden        case KM_ULONG_REP: {
3549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            uint64_t value = in.readInt64();
3559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_long(tag, value);
3569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_DATE: {
3599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            uint64_t value = in.readInt64();
3609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_date(tag, value);
3619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BOOL: {
3649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_bool(tag);
3659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BIGNUM:
3689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case KM_BYTES: {
3699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ssize_t length = in.readInt32();
3709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            uint8_t* data = NULL;
3719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            size_t ulength = 0;
3729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (length >= 0) {
3739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                ulength = (size_t) length;
3749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                // use malloc here so we can use keymaster_free_param_values
3759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                // consistently.
3769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                data = reinterpret_cast<uint8_t*>(malloc(ulength));
3779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                const void* buf = in.readInplace(ulength);
3789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                if (!buf || !data) {
3799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                    ALOGE("Failed to allocate buffer for keymaster blob param");
380067042f6d7be14cb0f01388c41af597caf8e60feShawn Willden                    free(data);
3819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                    return false;
3829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                }
3839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                memcpy(data, buf, ulength);
3849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
3859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            *out = keymaster_param_blob(tag, data, ulength);
3869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            break;
3879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        default: {
3899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Unsupported keymaster_tag_t %d", tag);
3909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return false;
3919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
3929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
3939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    return true;
3949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
3959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
3966432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker/**
3976432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker * Read a byte array from in. The data at *data is still owned by the parcel
3986432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker */
3996432df7173778954f3e2dfe7d495ab5daa6983abChad Brubakerstatic void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) {
4006432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker    ssize_t slength = in.readInt32();
4016432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker    if (slength > 0) {
4026432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        *data = reinterpret_cast<const uint8_t*>(in.readInplace(slength));
4036432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        if (*data) {
4046432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            *length = static_cast<size_t>(slength);
4056432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        } else {
4066432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            *length = 0;
4076432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        }
4086432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker    } else {
4096432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        *data = NULL;
4106432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker        *length = 0;
4116432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker    }
4126432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker}
4136432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker
4149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker// Read a keymaster_key_param_t* from a Parcel for use in a
4159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker// keymaster_key_characteristics_t. This will be free'd by calling
4169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker// keymaster_free_key_characteristics.
4179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakerstatic keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
4189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    ssize_t slength = in.readInt32();
4199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    *length = 0;
4209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (slength < 0) {
4219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return NULL;
4229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
4239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    *length = (size_t) slength;
4249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
4259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return NULL;
4269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
4279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    keymaster_key_param_t* list =
4289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
4299899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                                                            sizeof(keymaster_key_param_t)));
4309899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    if (!list) {
4319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
4329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        goto err;
4339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
4349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    for (size_t i = 0; i < *length ; i++) {
4359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (!readKeymasterArgumentFromParcel(in, &list[i])) {
4369899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGE("Failed to read keymaster argument");
4379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            keymaster_free_param_values(list, i);
4389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            goto err;
4399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
4409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
4419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    return list;
4429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubakererr:
4439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    free(list);
4449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    return NULL;
4459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
4469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
447d663442b590b59250062335cc057478001b8e439Chad Brubakerstatic std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
44850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    std::unique_ptr<keymaster_blob_t> blob (new keymaster_blob_t);
44950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    if (!readKeymasterBlob(in, blob.get())) {
45050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        blob.reset();
4519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
452d663442b590b59250062335cc057478001b8e439Chad Brubaker    return blob;
4539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker}
4549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
45507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass BpKeystoreService: public BpInterface<IKeystoreService>
45607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root{
45707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic:
45807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    BpKeystoreService(const sp<IBinder>& impl)
45907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        : BpInterface<IKeystoreService>(impl)
46007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
46107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
46207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
46307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    // test ping
464e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker    virtual int32_t getState(int32_t userId)
46507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
46607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
46707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
468e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        data.writeInt32(userId);
469e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply);
47007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
471e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("getState() could not contact remote: %d\n", status);
47207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
47307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
47407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
47507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
47607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
477e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("getState() caught exception %d\n", err);
47807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
47907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
48007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
48107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
48207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
483ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker    virtual int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength)
48407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
48507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
48607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
48707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
488ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker        data.writeInt32(uid);
48907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
49007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
49107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("get() could not contact remote: %d\n", status);
49207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
49307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
49407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
49507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ssize_t len = reply.readInt32();
49607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
49707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t ulen = (size_t) len;
49807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* buf = reply.readInplace(ulen);
49907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *item = (uint8_t*) malloc(ulen);
50007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (*item != NULL) {
50107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                memcpy(*item, buf, ulen);
50207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *itemLength = ulen;
50307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
50407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                ALOGE("out of memory allocating output array in get");
50507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *itemLength = 0;
50607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
50707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } else {
50807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *itemLength = 0;
50907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
51007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
51107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("get() caught exception %d\n", err);
51207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
51307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
51407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return 0;
51507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
51607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
5170c540aad5915e6aa34345049be96f28b64d0e84cKenny Root    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
5180c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t flags)
51907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
52007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
52107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
52207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
52307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(itemLength);
52407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        void* buf = data.writeInplace(itemLength);
52507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(buf, item, itemLength);
526b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
5270c540aad5915e6aa34345049be96f28b64d0e84cKenny Root        data.writeInt32(flags);
52807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
52907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
53007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() could not contact remote: %d\n", status);
53107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
53207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
53307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
53407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
53507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
53607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() caught exception %d\n", err);
53707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
53807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
53907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
54007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
54107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
542b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root    virtual int32_t del(const String16& name, int uid)
54307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
54407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
54507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
54607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
547b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
54807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
54907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
55007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("del() could not contact remote: %d\n", status);
55107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
55207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
55307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
55407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
55507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
55607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("del() caught exception %d\n", err);
55707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
55807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
55907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
56007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
56107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
562b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root    virtual int32_t exist(const String16& name, int uid)
56307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
56407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
56507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
56607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
567b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
56807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
56907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
57007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("exist() could not contact remote: %d\n", status);
57107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
57207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
57307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
57407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
57507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
57607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("exist() caught exception %d\n", err);
57707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
57807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
57907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
58007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
58107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
582e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker    virtual int32_t list(const String16& prefix, int uid, Vector<String16>* matches)
58307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
58407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
58507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
586e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        data.writeString16(prefix);
587b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
588e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply);
58907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
590e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("list() could not contact remote: %d\n", status);
59107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
59207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
59307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
59407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t numMatches = reply.readInt32();
59507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        for (int32_t i = 0; i < numMatches; i++) {
59607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            matches->push(reply.readString16());
59707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
59807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
59907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
600e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("list() caught exception %d\n", err);
60107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
60207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
60307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
60407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
60507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
60607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t reset()
60707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
60807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
60907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
61007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
61107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
61207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("reset() could not contact remote: %d\n", status);
61307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
61407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
61507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
61607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
61707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
61807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("reset() caught exception %d\n", err);
61907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
62007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
62107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
62207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
62307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
62496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    virtual int32_t onUserPasswordChanged(int32_t userId, const String16& password)
62507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
62607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
62707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
62896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        data.writeInt32(userId);
62907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(password);
63096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        status_t status = remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data,
63196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                                             &reply);
63207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
63396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status);
63407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
63507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
63607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
63707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
63807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
63996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            ALOGD("onUserPasswordChanged() caught exception %d\n", err);
64007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
64107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
64207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
64307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
64407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
645e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker    virtual int32_t lock(int32_t userId)
64607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
64707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
64807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
649e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        data.writeInt32(userId);
65007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
65107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
65207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("lock() could not contact remote: %d\n", status);
65307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
65407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
65507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
65607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
65707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
65807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("lock() caught exception %d\n", err);
65907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
66007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
66107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
66207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
66307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
66496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    virtual int32_t unlock(int32_t userId, const String16& password)
66507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
66607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
66707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
66896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        data.writeInt32(userId);
66907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(password);
67007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
67107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
67207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("unlock() could not contact remote: %d\n", status);
67307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
67407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
67507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
67607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
67707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
67807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("unlock() caught exception %d\n", err);
67907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
68007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
68107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
68207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
68307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
684e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker    virtual bool isEmpty(int32_t userId)
68507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
68607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
68707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
688e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        data.writeInt32(userId);
689e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        status_t status = remote()->transact(BnKeystoreService::IS_EMPTY, data, &reply);
69007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
691e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("isEmpty() could not contact remote: %d\n", status);
692e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            return false;
69307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
69407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
69507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
69607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
697e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            ALOGD("isEmpty() caught exception %d\n", err);
698e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            return false;
69907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
700e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        return ret != 0;
70107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
70207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
70396427baf0094d50047049d329b0779c3c910402cKenny Root    virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
70496427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t flags, Vector<sp<KeystoreArg> >* args)
70507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
70607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
70707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
70807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
709b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
71096427baf0094d50047049d329b0779c3c910402cKenny Root        data.writeInt32(keyType);
71196427baf0094d50047049d329b0779c3c910402cKenny Root        data.writeInt32(keySize);
7120c540aad5915e6aa34345049be96f28b64d0e84cKenny Root        data.writeInt32(flags);
713468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker        data.writeInt32(1);
71496427baf0094d50047049d329b0779c3c910402cKenny Root        data.writeInt32(args->size());
71596427baf0094d50047049d329b0779c3c910402cKenny Root        for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
71696427baf0094d50047049d329b0779c3c910402cKenny Root            sp<KeystoreArg> item = *it;
71796427baf0094d50047049d329b0779c3c910402cKenny Root            size_t keyLength = item->size();
71896427baf0094d50047049d329b0779c3c910402cKenny Root            data.writeInt32(keyLength);
71996427baf0094d50047049d329b0779c3c910402cKenny Root            void* buf = data.writeInplace(keyLength);
72096427baf0094d50047049d329b0779c3c910402cKenny Root            memcpy(buf, item->data(), keyLength);
72196427baf0094d50047049d329b0779c3c910402cKenny Root        }
72207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
72307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
72407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("generate() could not contact remote: %d\n", status);
72507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
72607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
72707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
72807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
72907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
73007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("generate() caught exception %d\n", err);
73107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
73207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
73307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
73407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
73507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
7360c540aad5915e6aa34345049be96f28b64d0e84cKenny Root    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
7370c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int flags)
73807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
73907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
74007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
74107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
74207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(keyLength);
74307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        void* buf = data.writeInplace(keyLength);
74407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(buf, key, keyLength);
745b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        data.writeInt32(uid);
7460c540aad5915e6aa34345049be96f28b64d0e84cKenny Root        data.writeInt32(flags);
74707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
74807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
74907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() could not contact remote: %d\n", status);
75007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
75107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
75207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
75307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
75407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
75507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() caught exception %d\n", err);
75607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
75707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
75807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
75907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
76007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
76107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
76207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t* outLength)
76307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
76407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
76507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
76607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
76707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(inLength);
76807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        void* buf = data.writeInplace(inLength);
76907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(buf, in, inLength);
77007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
77107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
77207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() could not contact remote: %d\n", status);
77307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
77407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
77507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
77607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ssize_t len = reply.readInt32();
77707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
77807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t ulen = (size_t) len;
77907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* outBuf = reply.readInplace(ulen);
78007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out = (uint8_t*) malloc(ulen);
78107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (*out != NULL) {
78207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                memcpy((void*) *out, outBuf, ulen);
78307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *outLength = ulen;
78407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
78507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                ALOGE("out of memory allocating output array in sign");
78607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *outLength = 0;
78707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
78807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } else {
78907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *outLength = 0;
79007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
79107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
79207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("import() caught exception %d\n", err);
79307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
79407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
79507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return 0;
79607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
79707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
79807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
79907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const uint8_t* signature, size_t signatureLength)
80007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
80107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
80207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        void* buf;
80307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
80407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
80507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
80607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(inLength);
80707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        buf = data.writeInplace(inLength);
80807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(buf, in, inLength);
80907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(signatureLength);
81007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        buf = data.writeInplace(signatureLength);
81107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(buf, signature, signatureLength);
81207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
81307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
81407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("verify() could not contact remote: %d\n", status);
81507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
81607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
81707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
81807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
81907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
82007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("verify() caught exception %d\n", err);
82107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
82207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
82307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
82407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
82507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
82607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
82707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
82807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
82907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
83007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
83107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
83207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
83307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("get_pubkey() could not contact remote: %d\n", status);
83407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
83507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
83607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
83707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ssize_t len = reply.readInt32();
83807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
83907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t ulen = (size_t) len;
84007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* buf = reply.readInplace(ulen);
84107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *pubkey = (uint8_t*) malloc(ulen);
84207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (*pubkey != NULL) {
84307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                memcpy(*pubkey, buf, ulen);
84407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *pubkeyLength = ulen;
84507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
84607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                ALOGE("out of memory allocating output array in get_pubkey");
84707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                *pubkeyLength = 0;
84807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
84907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } else {
85007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *pubkeyLength = 0;
85107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
85207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
85307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("get_pubkey() caught exception %d\n", err);
85407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
85507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
85607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return 0;
85707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     }
85807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
85907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t grant(const String16& name, int32_t granteeUid)
86007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
86107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
86207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
86307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
86407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(granteeUid);
86507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
86607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
86707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("grant() could not contact remote: %d\n", status);
86807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
86907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
87007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
87107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
87207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
87307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("grant() caught exception %d\n", err);
87407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
87507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
87607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
87707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
87807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
87907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
88007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
88107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
88207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
88307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
88407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInt32(granteeUid);
88507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
88607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
88707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("ungrant() could not contact remote: %d\n", status);
88807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
88907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
89007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
89107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t ret = reply.readInt32();
89207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
89307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("ungrant() caught exception %d\n", err);
89407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
89507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
89607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
89707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
89807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
899ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker    int64_t getmtime(const String16& name, int32_t uid)
90007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
90107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Parcel data, reply;
90207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
90307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        data.writeString16(name);
904ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker        data.writeInt32(uid);
90507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
90607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (status != NO_ERROR) {
90707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("getmtime() could not contact remote: %d\n", status);
90807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
90907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
91007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int32_t err = reply.readExceptionCode();
91107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int64_t ret = reply.readInt64();
91207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (err < 0) {
91307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("getmtime() caught exception %d\n", err);
91407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
91507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
91607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ret;
91707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
9180225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
919d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
920d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t destUid)
9210225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root    {
9220225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        Parcel data, reply;
9230225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
924d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        data.writeString16(srcKey);
925d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        data.writeInt32(srcUid);
926d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        data.writeString16(destKey);
927d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        data.writeInt32(destUid);
928d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
9290225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        if (status != NO_ERROR) {
930d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("duplicate() could not contact remote: %d\n", status);
9310225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return -1;
9320225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
9330225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        int32_t err = reply.readExceptionCode();
9340225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        int32_t ret = reply.readInt32();
9350225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        if (err < 0) {
936d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("duplicate() caught exception %d\n", err);
9370225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return -1;
9380225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
9390225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        return ret;
9400225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root    }
9414306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root
9421b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    virtual int32_t is_hardware_backed(const String16& keyType)
9434306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root    {
9444306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        Parcel data, reply;
9454306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
9461b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        data.writeString16(keyType);
9474306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
9484306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        if (status != NO_ERROR) {
9494306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
9504306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            return -1;
9514306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        }
9524306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        int32_t err = reply.readExceptionCode();
9534306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        int32_t ret = reply.readInt32();
9544306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        if (err < 0) {
9554306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            ALOGD("is_hardware_backed() caught exception %d\n", err);
9564306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            return -1;
9574306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        }
9584306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        return ret;
9594306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root    }
9602ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root
9612ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root    virtual int32_t clear_uid(int64_t uid)
9622ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root    {
9632ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        Parcel data, reply;
9642ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
9652ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        data.writeInt64(uid);
9662ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
9672ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        if (status != NO_ERROR) {
9682ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            ALOGD("clear_uid() could not contact remote: %d\n", status);
9692ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            return -1;
9702ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        }
9712ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        int32_t err = reply.readExceptionCode();
9722ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        int32_t ret = reply.readInt32();
9732ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        if (err < 0) {
9742ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            ALOGD("clear_uid() caught exception %d\n", err);
9752ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            return -1;
9762ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        }
9772ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        return ret;
9782ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root    }
9794e865753346fc6a075966972a7a98051818859dbRobin Lee
9809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
9819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
9829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
9839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
9849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeByteArray(bufLength, buf);
9859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
9869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
9879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("addRngEntropy() could not contact remote: %d\n", status);
9889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return -1;
9899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
9909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
9919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t ret = reply.readInt32();
9929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
9939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("addRngEntropy() caught exception %d\n", err);
9949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return -1;
9959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
9969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return ret;
9979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    };
9989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
9999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
1000154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
1001154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                KeyCharacteristics* outCharacteristics)
10029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
10039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
10049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
10059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeString16(name);
10069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(1);
10079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.writeToParcel(&data);
1008154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        data.writeByteArray(entropyLength, entropy);
10099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(uid);
10109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(flags);
10119899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
10129899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
10139899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("generateKey() could not contact remote: %d\n", status);
10149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
10179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t ret = reply.readInt32();
10189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
10199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("generateKey() caught exception %d\n", err);
10209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0 && outCharacteristics) {
10239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics->readFromParcel(reply);
10249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return ret;
10269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
10279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual int32_t getKeyCharacteristics(const String16& name,
1028d663442b590b59250062335cc057478001b8e439Chad Brubaker                                          const keymaster_blob_t* clientId,
1029d663442b590b59250062335cc057478001b8e439Chad Brubaker                                          const keymaster_blob_t* appData,
1030ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker                                          int32_t uid, KeyCharacteristics* outCharacteristics)
10319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
10329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
10339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
10349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeString16(name);
1035d663442b590b59250062335cc057478001b8e439Chad Brubaker        if (clientId) {
1036d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeByteArray(clientId->data_length, clientId->data);
1037d663442b590b59250062335cc057478001b8e439Chad Brubaker        } else {
1038d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeInt32(-1);
1039d663442b590b59250062335cc057478001b8e439Chad Brubaker        }
1040d663442b590b59250062335cc057478001b8e439Chad Brubaker        if (appData) {
1041d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeByteArray(appData->data_length, appData->data);
1042d663442b590b59250062335cc057478001b8e439Chad Brubaker        } else {
1043d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeInt32(-1);
1044d663442b590b59250062335cc057478001b8e439Chad Brubaker        }
1045ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker        data.writeInt32(uid);
10469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
10479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                                             data, &reply);
10489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
10499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
10509899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
10539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t ret = reply.readInt32();
10549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
10559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("getKeyCharacteristics() caught exception %d\n", err);
10569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0 && outCharacteristics) {
10599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics->readFromParcel(reply);
10609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return ret;
10629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
10639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
10649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                              keymaster_key_format_t format, const uint8_t *keyData,
10659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                              size_t keyLength, int uid, int flags,
10669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                              KeyCharacteristics* outCharacteristics)
10679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
10689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
10699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
10709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeString16(name);
10719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(1);
10729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.writeToParcel(&data);
10739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(format);
10749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeByteArray(keyLength, keyData);
10759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(uid);
10769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(flags);
10779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
10789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
10799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("importKey() could not contact remote: %d\n", status);
10809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
10839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t ret = reply.readInt32();
10849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
10859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("importKey() caught exception %d\n", err);
10869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
10879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0 && outCharacteristics) {
10899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics->readFromParcel(reply);
10909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
10919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return ret;
10929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
10939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
10949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual void exportKey(const String16& name, keymaster_key_format_t format,
1095d663442b590b59250062335cc057478001b8e439Chad Brubaker                           const keymaster_blob_t* clientId,
1096ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker                           const keymaster_blob_t* appData, int32_t uid, ExportResult* result)
10979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
10989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (!result) {
10999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
11029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
11039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
11049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeString16(name);
11059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(format);
1106d663442b590b59250062335cc057478001b8e439Chad Brubaker        if (clientId) {
1107d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeByteArray(clientId->data_length, clientId->data);
1108d663442b590b59250062335cc057478001b8e439Chad Brubaker        } else {
1109d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeInt32(-1);
1110d663442b590b59250062335cc057478001b8e439Chad Brubaker        }
1111d663442b590b59250062335cc057478001b8e439Chad Brubaker        if (appData) {
1112d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeByteArray(appData->data_length, appData->data);
1113d663442b590b59250062335cc057478001b8e439Chad Brubaker        } else {
1114d663442b590b59250062335cc057478001b8e439Chad Brubaker            data.writeInt32(-1);
1115d663442b590b59250062335cc057478001b8e439Chad Brubaker        }
1116ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker        data.writeInt32(uid);
11179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
11189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
11199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("exportKey() could not contact remote: %d\n", status);
11209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
11249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
11259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("exportKey() caught exception %d\n", err);
11269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11299899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0) {
11309899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->readFromParcel(reply);
11319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
11339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
11349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual void begin(const sp<IBinder>& appToken, const String16& name,
11359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                       keymaster_purpose_t purpose, bool pruneable,
1136154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                       const KeymasterArguments& params, const uint8_t* entropy,
1137ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker                       size_t entropyLength, int32_t uid, OperationResult* result)
11389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
113957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker        if (!result) {
11409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
11439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
11449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeStrongBinder(appToken);
11459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeString16(name);
11469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(purpose);
11479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(pruneable ? 1 : 0);
11489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(1);
11499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.writeToParcel(&data);
1150154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        data.writeByteArray(entropyLength, entropy);
1151ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker        data.writeInt32(uid);
11529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
11539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
11549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("begin() could not contact remote: %d\n", status);
11559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
11599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
11609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("begin() caught exception %d\n", err);
11619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0) {
11659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->readFromParcel(reply);
11669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
11689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
11699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
117040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                        const uint8_t* opData, size_t dataLength, OperationResult* result)
11719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
11729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (!result) {
11739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
11769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
11779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeStrongBinder(token);
11789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(1);
11799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.writeToParcel(&data);
11809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeByteArray(dataLength, opData);
11819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
11829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
11839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("update() could not contact remote: %d\n", status);
11849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
11889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
11899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("update() caught exception %d\n", err);
11909899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
11919899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
11929899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0) {
11949899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->readFromParcel(reply);
11959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
11969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
11979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
11989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
11990d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker                        const uint8_t* signature, size_t signatureLength,
12000d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker                        const uint8_t* entropy, size_t entropyLength,
12010d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker                        OperationResult* result)
12029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
12039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (!result) {
12049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
12059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
12079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
12089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeStrongBinder(token);
12099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInt32(1);
12109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        params.writeToParcel(&data);
12119899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeByteArray(signatureLength, signature);
12120d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker        data.writeByteArray(entropyLength, entropy);
12139899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
12149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
12159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("finish() could not contact remote: %d\n", status);
12169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
12179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
12189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
12209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
12219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("finish() caught exception %d\n", err);
12229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
12239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return;
12249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (reply.readInt32() != 0) {
12269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result->readFromParcel(reply);
12279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
12299899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
12309899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    virtual int32_t abort(const sp<IBinder>& token)
12319899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    {
12329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        Parcel data, reply;
12339899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
12349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        data.writeStrongBinder(token);
12352ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply);
12369899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (status != NO_ERROR) {
12379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("abort() could not contact remote: %d\n", status);
12389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
12399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t err = reply.readExceptionCode();
12419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        int32_t ret = reply.readInt32();
12429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        if (err < 0) {
12439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ALOGD("abort() caught exception %d\n", err);
12449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return KM_ERROR_UNKNOWN_ERROR;
12459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
12469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        return ret;
12479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
12482ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
12492ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    virtual bool isOperationAuthorized(const sp<IBinder>& token)
12502ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    {
12512ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        Parcel data, reply;
12522ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
12532ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        data.writeStrongBinder(token);
12542ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        status_t status = remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data,
12552ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker                                             &reply);
12562ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        if (status != NO_ERROR) {
12572ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            ALOGD("isOperationAuthorized() could not contact remote: %d\n", status);
12582ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return false;
12592ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
12602ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        int32_t err = reply.readExceptionCode();
12612ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        int32_t ret = reply.readInt32();
12622ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        if (err < 0) {
12632ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            ALOGD("isOperationAuthorized() caught exception %d\n", err);
12642ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return false;
12652ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
12662ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        return ret == 1;
12672ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    }
12682ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
12692ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    virtual int32_t addAuthToken(const uint8_t* token, size_t length)
12702ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    {
12712ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        Parcel data, reply;
12722ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
12732ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        data.writeByteArray(length, token);
12742ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply);
12752ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        if (status != NO_ERROR) {
12762ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            ALOGD("addAuthToken() could not contact remote: %d\n", status);
12772ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return -1;
12782ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
12792ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        int32_t err = reply.readExceptionCode();
12802ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        int32_t ret = reply.readInt32();
12812ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        if (err < 0) {
12822ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            ALOGD("addAuthToken() caught exception %d\n", err);
12832ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return -1;
12842ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
12852ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        return ret;
12862ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    };
1287c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1288c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    virtual int32_t onUserAdded(int32_t userId, int32_t parentId)
1289c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    {
1290c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        Parcel data, reply;
1291c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1292c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        data.writeInt32(userId);
1293c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        data.writeInt32(parentId);
1294c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply);
1295c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (status != NO_ERROR) {
1296c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            ALOGD("onUserAdded() could not contact remote: %d\n", status);
1297c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return -1;
1298c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1299c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        int32_t err = reply.readExceptionCode();
1300c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        int32_t ret = reply.readInt32();
1301c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (err < 0) {
1302c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            ALOGD("onUserAdded() caught exception %d\n", err);
1303c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return -1;
1304c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1305c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        return ret;
1306c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    }
1307c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1308c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    virtual int32_t onUserRemoved(int32_t userId)
1309c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    {
1310c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        Parcel data, reply;
1311c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1312c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        data.writeInt32(userId);
1313c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply);
1314c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (status != NO_ERROR) {
1315c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            ALOGD("onUserRemoved() could not contact remote: %d\n", status);
1316c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return -1;
1317c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1318c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        int32_t err = reply.readExceptionCode();
1319c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        int32_t ret = reply.readInt32();
1320c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (err < 0) {
1321c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            ALOGD("onUserRemoved() caught exception %d\n", err);
1322c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return -1;
1323c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1324c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        return ret;
1325c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    }
1326c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
132750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
132850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden                              KeymasterCertificateChain* outChain) {
132950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (!outChain)
133050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            return KM_ERROR_OUTPUT_PARAMETER_NULL;
133150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
133250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        Parcel data, reply;
133350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
133450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        data.writeString16(name);
133550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        data.writeInt32(1);  // params is not NULL.
133650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        params.writeToParcel(&data);
133750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
133850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        status_t status = remote()->transact(BnKeystoreService::ATTEST_KEY, data, &reply);
133950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (status != NO_ERROR) {
134050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            ALOGD("attestkey() count not contact remote: %d\n", status);
134150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            return KM_ERROR_UNKNOWN_ERROR;
134250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        }
134350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        int32_t err = reply.readExceptionCode();
134450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        int32_t ret = reply.readInt32();
134550eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (err < 0) {
134650eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            ALOGD("attestKey() caught exception %d\n", err);
134750eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            return KM_ERROR_UNKNOWN_ERROR;
134850eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        }
134950eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        if (reply.readInt32() != 0) {
135050eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden            outChain->readFromParcel(reply);
135150eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        }
135250eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden        return ret;
135350eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden    }
135450eb1b2f89ca455b2e9caa635bfe0b5ed94b416aShawn Willden
135507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
135607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1357468fc6935176d1615002956fcbe01fd3341c75ecChad BrubakerIMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
135807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
135907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root// ----------------------------------------------------------------------
136007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
136107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatus_t BnKeystoreService::onTransact(
136207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
136307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root{
136407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    switch(code) {
1365e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        case GET_STATE: {
136607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
1367e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t userId = data.readInt32();
1368e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t ret = getState(userId);
136907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
137007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
137107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
137207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
137307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case GET: {
137407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
137507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
1376ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t uid = data.readInt32();
137707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            void* out = NULL;
137807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t outSize = 0;
1379ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t ret = get(name, uid, (uint8_t**) &out, &outSize);
138007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
138107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (ret == 1) {
138207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                reply->writeInt32(outSize);
138307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                void* buf = reply->writeInplace(outSize);
138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                memcpy(buf, out, outSize);
138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                free(out);
138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
138707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                reply->writeInt32(-1);
138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
139007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case INSERT: {
139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
139307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
139407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ssize_t inSize = data.readInt32();
139507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* in;
139607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
139707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = data.readInplace(inSize);
139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
139907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = NULL;
140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                inSize = 0;
140107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
1402b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int uid = data.readInt32();
14030c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t flags = data.readInt32();
14040c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
140507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
140707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
140807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case DEL: {
141007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
141107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
1412b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int uid = data.readInt32();
1413b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int32_t ret = del(name, uid);
141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
141707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
141807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case EXIST: {
141907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
142007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
1421b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int uid = data.readInt32();
1422b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int32_t ret = exist(name, uid);
142307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
142407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
1427e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        case LIST: {
142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
1429e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            String16 prefix = data.readString16();
1430b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int uid = data.readInt32();
143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            Vector<String16> matches;
1432e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t ret = list(prefix, uid, &matches);
143307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
143407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(matches.size());
143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            Vector<String16>::const_iterator it = matches.begin();
143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            for (; it != matches.end(); ++it) {
143707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                reply->writeString16(*it);
143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
144107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case RESET: {
144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t ret = reset();
144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
144607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
144707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
144996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        case ON_USER_PASSWORD_CHANGED: {
145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
145196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            int32_t userId = data.readInt32();
145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 pass = data.readString16();
145396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            int32_t ret = onUserPasswordChanged(userId, pass);
145407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
145507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
145707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
145807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case LOCK: {
145907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
1460e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t userId = data.readInt32();
1461e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t ret = lock(userId);
146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case UNLOCK: {
146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
146896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            int32_t userId = data.readInt32();
146907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 pass = data.readString16();
147096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            int32_t ret = unlock(userId, pass);
147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
147207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
147307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
147407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
1475e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker        case IS_EMPTY: {
147607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
1477e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            int32_t userId = data.readInt32();
1478e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            bool ret = isEmpty(userId);
147907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
1480e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker            reply->writeInt32(ret ? 1 : 0);
148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case GENERATE: {
148407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
148696427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t uid = data.readInt32();
148796427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t keyType = data.readInt32();
148896427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t keySize = data.readInt32();
14890c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t flags = data.readInt32();
149096427baf0094d50047049d329b0779c3c910402cKenny Root            Vector<sp<KeystoreArg> > args;
1491468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker            int32_t argsPresent = data.readInt32();
1492468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker            if (argsPresent == 1) {
1493468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                ssize_t numArgs = data.readInt32();
1494ed4f566a926d935ee7e2a158d75bbd050ef85778Chad Brubaker                if (numArgs > MAX_GENERATE_ARGS) {
1495ed4f566a926d935ee7e2a158d75bbd050ef85778Chad Brubaker                    return BAD_VALUE;
1496ed4f566a926d935ee7e2a158d75bbd050ef85778Chad Brubaker                }
1497468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                if (numArgs > 0) {
1498468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                    for (size_t i = 0; i < (size_t) numArgs; i++) {
1499468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                        ssize_t inSize = data.readInt32();
1500468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                        if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1501468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                            sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize),
1502468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                                                                  inSize);
1503468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                            args.push_back(arg);
1504468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                        } else {
1505468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                            args.push_back(NULL);
1506468fc6935176d1615002956fcbe01fd3341c75ecChad Brubaker                        }
150796427baf0094d50047049d329b0779c3c910402cKenny Root                    }
150896427baf0094d50047049d329b0779c3c910402cKenny Root                }
150996427baf0094d50047049d329b0779c3c910402cKenny Root            }
151096427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
151207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case IMPORT: {
151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ssize_t inSize = data.readInt32();
151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* in;
152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = data.readInplace(inSize);
152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = NULL;
152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                inSize = 0;
152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
1526b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            int uid = data.readInt32();
15270c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t flags = data.readInt32();
15280c540aad5915e6aa34345049be96f28b64d0e84cKenny Root            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case SIGN: {
153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
153507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ssize_t inSize = data.readInt32();
153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* in;
153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = data.readInplace(inSize);
154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = NULL;
154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                inSize = 0;
154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            void* out = NULL;
154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t outSize = 0;
154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
1548b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            if (outSize > 0 && out != NULL) {
1549b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                reply->writeInt32(outSize);
1550b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                void* buf = reply->writeInplace(outSize);
1551b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                memcpy(buf, out, outSize);
15523a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker                delete[] reinterpret_cast<uint8_t*>(out);
1553b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            } else {
1554e289c404b9d2735fbd67c42086e33c972b46aa33Kenny Root                reply->writeInt32(-1);
1555b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            }
155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
155707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
155907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case VERIFY: {
156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ssize_t inSize = data.readInt32();
156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* in;
156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = data.readInplace(inSize);
156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                in = NULL;
156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                inSize = 0;
156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ssize_t sigSize = data.readInt32();
157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const void* sig;
157207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                sig = data.readInplace(sigSize);
157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            } else {
157507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                sig = NULL;
157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                sigSize = 0;
157707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                    (size_t) sigSize);
158007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret ? 1 : 0);
158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case GET_PUBKEY: {
158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            void* out = NULL;
158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t outSize = 0;
158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
1591b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            if (outSize > 0 && out != NULL) {
1592b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                reply->writeInt32(outSize);
1593b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                void* buf = reply->writeInplace(outSize);
1594b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                memcpy(buf, out, outSize);
1595b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root                free(out);
1596b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            } else {
1597e289c404b9d2735fbd67c42086e33c972b46aa33Kenny Root                reply->writeInt32(-1);
1598b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root            }
159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
1601b03c9fb5f9c058a8ae0485c986a8ab934ab73eaaKenny Root        } break;
160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case GRANT: {
160307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
160407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
160507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t granteeUid = data.readInt32();
160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t ret = grant(name, granteeUid);
160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
160907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
161007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case UNGRANT: {
161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
161407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t granteeUid = data.readInt32();
161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            int32_t ret = ungrant(name, granteeUid);
161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt32(ret);
161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        case GETMTIME: {
162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            String16 name = data.readString16();
1623ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t uid = data.readInt32();
1624ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int64_t ret = getmtime(name, uid);
162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeNoException();
162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            reply->writeInt64(ret);
162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return NO_ERROR;
162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } break;
1629d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        case DUPLICATE: {
16300225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
1631d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            String16 srcKey = data.readString16();
1632d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t srcUid = data.readInt32();
1633d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            String16 destKey = data.readString16();
1634d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t destUid = data.readInt32();
1635d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
16360225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            reply->writeNoException();
16370225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            reply->writeInt32(ret);
16380225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return NO_ERROR;
16390225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        } break;
16404306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        case IS_HARDWARE_BACKED: {
16414306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
16421b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            String16 keyType = data.readString16();
16431b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            int32_t ret = is_hardware_backed(keyType);
16444306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            reply->writeNoException();
16454306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            reply->writeInt32(ret);
16464306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root            return NO_ERROR;
16474306123e81371bd8bd85f77c2375d29ac53ff771Kenny Root        }
16482ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        case CLEAR_UID: {
16492ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            CHECK_INTERFACE(IKeystoreService, data, reply);
16502ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            int64_t uid = data.readInt64();
16512ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            int32_t ret = clear_uid(uid);
16522ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            reply->writeNoException();
16532ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            reply->writeInt32(ret);
16542ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root            return NO_ERROR;
16552ecc7a1efbb21d86d38b9e0348dfbf0e1213d920Kenny Root        }
16569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case ADD_RNG_ENTROPY: {
16579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
16586432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            const uint8_t* bytes = NULL;
16596432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            size_t size = 0;
16606432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            readByteArray(data, &bytes, &size);
16619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t ret = addRngEntropy(bytes, size);
16629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
16639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(ret);
16649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
16659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
16669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case GENERATE_KEY: {
16679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
16689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            String16 name = data.readString16();
16699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeymasterArguments args;
16709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.readInt32() != 0) {
16719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                args.readFromParcel(data);
16729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
1673154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            const uint8_t* entropy = NULL;
1674154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            size_t entropyLength = 0;
1675154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            readByteArray(data, &entropy, &entropyLength);
16769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t uid = data.readInt32();
16779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t flags = data.readInt32();
16789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeyCharacteristics outCharacteristics;
1679154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
1680154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                      &outCharacteristics);
16819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
16829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(ret);
16839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
16849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics.writeToParcel(reply);
16859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
16869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
16879899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case GET_KEY_CHARACTERISTICS: {
16889899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
16899899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            String16 name = data.readString16();
1690d663442b590b59250062335cc057478001b8e439Chad Brubaker            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1691d663442b590b59250062335cc057478001b8e439Chad Brubaker            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
1692ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t uid = data.readInt32();
16939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeyCharacteristics outCharacteristics;
1694ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(), uid,
1695d663442b590b59250062335cc057478001b8e439Chad Brubaker                                            &outCharacteristics);
16969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
16979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(ret);
16989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
16999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics.writeToParcel(reply);
17009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
17019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
17029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case IMPORT_KEY: {
17039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
17049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            String16 name = data.readString16();
17059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeymasterArguments args;
17069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.readInt32() != 0) {
17079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                args.readFromParcel(data);
17089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
17099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
17106432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            const uint8_t* keyData = NULL;
17116432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            size_t keyLength = 0;
17126432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            readByteArray(data, &keyData, &keyLength);
17139899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t uid = data.readInt32();
17149899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t flags = data.readInt32();
17159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeyCharacteristics outCharacteristics;
17166432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
17179899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                                    &outCharacteristics);
17189899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
17199899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(ret);
17209899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
17219899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            outCharacteristics.writeToParcel(reply);
17229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
17239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
17249899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
17259899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case EXPORT_KEY: {
17269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
17279899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            String16 name = data.readString16();
17289899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
1729d663442b590b59250062335cc057478001b8e439Chad Brubaker            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1730d663442b590b59250062335cc057478001b8e439Chad Brubaker            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
1731ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t uid = data.readInt32();
17329899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            ExportResult result;
1733ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            exportKey(name, format, clientId.get(), appData.get(), uid, &result);
17349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
17359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
17369899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result.writeToParcel(reply);
17379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
17389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
17399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
17409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case BEGIN: {
17419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
17429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            sp<IBinder> token = data.readStrongBinder();
17439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            String16 name = data.readString16();
17449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
17459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            bool pruneable = data.readInt32() != 0;
17469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeymasterArguments args;
17479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.readInt32() != 0) {
17489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                args.readFromParcel(data);
17499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
1750154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            const uint8_t* entropy = NULL;
1751154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            size_t entropyLength = 0;
1752154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            readByteArray(data, &entropy, &entropyLength);
1753ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            int32_t uid = data.readInt32();
17549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            OperationResult result;
1755ad6a7f5f988d4c7d1ac66c46052f29bb74745a3eChad Brubaker            begin(token, name, purpose, pruneable, args, entropy, entropyLength, uid, &result);
17569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
17579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
17589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result.writeToParcel(reply);
17599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
17609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
17619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
17629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case UPDATE: {
17639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
17649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            sp<IBinder> token = data.readStrongBinder();
17659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeymasterArguments args;
17669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.readInt32() != 0) {
17679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                args.readFromParcel(data);
17689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
17696432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            const uint8_t* buf = NULL;
17706432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            size_t bufLength = 0;
17716432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            readByteArray(data, &buf, &bufLength);
17729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            OperationResult result;
17736432df7173778954f3e2dfe7d495ab5daa6983abChad Brubaker            update(token, args, buf, bufLength, &result);
17749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
17759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
17769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result.writeToParcel(reply);
17779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
17789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
17799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
17809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case FINISH: {
17819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
17829899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            sp<IBinder> token = data.readStrongBinder();
17839899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            KeymasterArguments args;
17849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            if (data.readInt32() != 0) {
17859899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker                args.readFromParcel(data);
17869899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            }
17870d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            const uint8_t* signature = NULL;
17880d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            size_t signatureLength = 0;
17890d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            readByteArray(data, &signature, &signatureLength);
17900d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            const uint8_t* entropy = NULL;
17910d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            size_t entropyLength = 0;
17920d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            readByteArray(data, &entropy, &entropyLength);
17939899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            OperationResult result;
17940d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker            finish(token, args, signature, signatureLength, entropy, entropyLength,  &result);
17959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
17969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(1);
17979899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            result.writeToParcel(reply);
17989899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
17999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
18009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
18019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        case ABORT: {
18029899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
18039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            sp<IBinder> token = data.readStrongBinder();
18049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            int32_t result = abort(token);
18059899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeNoException();
18069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            reply->writeInt32(result);
18079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
18089899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker            return NO_ERROR;
18099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker        }
18102ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        case IS_OPERATION_AUTHORIZED: {
18112ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
18122ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            sp<IBinder> token = data.readStrongBinder();
18132ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            bool result = isOperationAuthorized(token);
18142ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            reply->writeNoException();
18152ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            reply->writeInt32(result ? 1 : 0);
18162ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
18172ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return NO_ERROR;
18182ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
18192ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        case ADD_AUTH_TOKEN: {
18202ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
18212ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            const uint8_t* token_bytes = NULL;
18222ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            size_t size = 0;
18232ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            readByteArray(data, &token_bytes, &size);
18242ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            int32_t result = addAuthToken(token_bytes, size);
18252ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            reply->writeNoException();
18262ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            reply->writeInt32(result);
18272ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
18282ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return NO_ERROR;
18292ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
1830c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        case ON_USER_ADDED: {
1831c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
1832c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            int32_t userId = data.readInt32();
1833c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            int32_t parentId = data.readInt32();
1834c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            int32_t result = onUserAdded(userId, parentId);
1835c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            reply->writeNoException();
1836c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            reply->writeInt32(result);
1837c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1838c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return NO_ERROR;
1839c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1840c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        case ON_USER_REMOVED: {
1841c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            CHECK_INTERFACE(IKeystoreService, data, reply);
1842c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            int32_t userId = data.readInt32();
1843c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            int32_t result = onUserRemoved(userId);
1844c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            reply->writeNoException();
1845c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            reply->writeInt32(result);
1846c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1847c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return NO_ERROR;
1848c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
18493976b6c43e2809662940d52306e03b2733112d05Shawn Willden        case ATTEST_KEY: {
18503976b6c43e2809662940d52306e03b2733112d05Shawn Willden            CHECK_INTERFACE(IKeystoreService, data, reply);
18513976b6c43e2809662940d52306e03b2733112d05Shawn Willden            String16 name = data.readString16();
18523976b6c43e2809662940d52306e03b2733112d05Shawn Willden            KeymasterArguments params;
18533976b6c43e2809662940d52306e03b2733112d05Shawn Willden            if (data.readInt32() != 0) {
18543976b6c43e2809662940d52306e03b2733112d05Shawn Willden                params.readFromParcel(data);
18553976b6c43e2809662940d52306e03b2733112d05Shawn Willden            }
18563976b6c43e2809662940d52306e03b2733112d05Shawn Willden            KeymasterCertificateChain chain;
18573976b6c43e2809662940d52306e03b2733112d05Shawn Willden            int ret = attestKey(name, params, &chain);
18583976b6c43e2809662940d52306e03b2733112d05Shawn Willden            reply->writeNoException();
18593976b6c43e2809662940d52306e03b2733112d05Shawn Willden            reply->writeInt32(ret);
18603976b6c43e2809662940d52306e03b2733112d05Shawn Willden            reply->writeInt32(1);
18613976b6c43e2809662940d52306e03b2733112d05Shawn Willden            chain.writeToParcel(reply);
18623976b6c43e2809662940d52306e03b2733112d05Shawn Willden
18633976b6c43e2809662940d52306e03b2733112d05Shawn Willden            return NO_ERROR;
18643976b6c43e2809662940d52306e03b2733112d05Shawn Willden        }
186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        default:
186607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return BBinder::onTransact(code, data, reply, flags);
186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
186907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
187007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root// ----------------------------------------------------------------------------
187107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
187207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android
1873