IKeystoreService.cpp revision 2a36a4f1d738185619b9aa48260fb34a39d04c37
1/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <stdint.h>
19#include <sys/limits.h>
20#include <sys/types.h>
21
22#define LOG_TAG "KeystoreService"
23#include <utils/Log.h>
24
25#include <binder/Parcel.h>
26#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28
29#include <keystore/IKeystoreService.h>
30
31namespace android {
32
33const ssize_t MAX_GENERATE_ARGS = 3;
34static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
35
36KeystoreArg::KeystoreArg(const void* data, size_t len)
37    : mData(data), mSize(len) {
38}
39
40KeystoreArg::~KeystoreArg() {
41}
42
43const void *KeystoreArg::data() const {
44    return mData;
45}
46
47size_t KeystoreArg::size() const {
48    return mSize;
49}
50
51OperationResult::OperationResult() : resultCode(0), token(), inputConsumed(0),
52    data(NULL), dataLength(0) {
53}
54
55OperationResult::~OperationResult() {
56}
57
58void OperationResult::readFromParcel(const Parcel& in) {
59    resultCode = in.readInt32();
60    token = in.readStrongBinder();
61    inputConsumed = in.readInt32();
62    ssize_t length = in.readInt32();
63    dataLength = 0;
64    if (length > 0) {
65        const void* buf = in.readInplace(length);
66        if (buf) {
67            data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
68            if (data.get()) {
69                memcpy(data.get(), buf, length);
70                dataLength = (size_t) length;
71            } else {
72                ALOGE("Failed to allocate OperationResult buffer");
73            }
74        } else {
75            ALOGE("Failed to readInplace OperationResult data");
76        }
77    }
78}
79
80void OperationResult::writeToParcel(Parcel* out) const {
81    out->writeInt32(resultCode);
82    out->writeStrongBinder(token);
83    out->writeInt32(inputConsumed);
84    out->writeInt32(dataLength);
85    if (dataLength && data) {
86        void* buf = out->writeInplace(dataLength);
87        if (buf) {
88            memcpy(buf, data.get(), dataLength);
89        } else {
90            ALOGE("Failed to writeInplace OperationResult data.");
91        }
92    }
93}
94
95ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
96}
97
98ExportResult::~ExportResult() {
99}
100
101void ExportResult::readFromParcel(const Parcel& in) {
102    resultCode = in.readInt32();
103    ssize_t length = in.readInt32();
104    dataLength = 0;
105    if (length > 0) {
106        const void* buf = in.readInplace(length);
107        if (buf) {
108            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
109            if (exportData.get()) {
110                memcpy(exportData.get(), buf, length);
111                dataLength = (size_t) length;
112            } else {
113                ALOGE("Failed to allocate ExportData buffer");
114            }
115        } else {
116            ALOGE("Failed to readInplace ExportData data");
117        }
118    }
119}
120
121void ExportResult::writeToParcel(Parcel* out) const {
122    out->writeInt32(resultCode);
123    out->writeInt32(dataLength);
124    if (exportData && dataLength) {
125        void* buf = out->writeInplace(dataLength);
126        if (buf) {
127            memcpy(buf, exportData.get(), dataLength);
128        } else {
129            ALOGE("Failed to writeInplace ExportResult data.");
130        }
131    }
132}
133
134KeymasterArguments::KeymasterArguments() {
135}
136
137KeymasterArguments::~KeymasterArguments() {
138    keymaster_free_param_values(params.data(), params.size());
139}
140
141void KeymasterArguments::readFromParcel(const Parcel& in) {
142    ssize_t length = in.readInt32();
143    size_t ulength = (size_t) length;
144    if (length < 0) {
145        ulength = 0;
146    }
147    keymaster_free_param_values(params.data(), params.size());
148    params.clear();
149    for(size_t i = 0; i < ulength; i++) {
150        keymaster_key_param_t param;
151        if (!readKeymasterArgumentFromParcel(in, &param)) {
152            ALOGE("Error reading keymaster argument from parcel");
153            break;
154        }
155        params.push_back(param);
156    }
157}
158
159void KeymasterArguments::writeToParcel(Parcel* out) const {
160    out->writeInt32(params.size());
161    for (auto param : params) {
162        out->writeInt32(1);
163        writeKeymasterArgumentToParcel(param, out);
164    }
165}
166
167KeyCharacteristics::KeyCharacteristics() {
168    memset((void*) &characteristics, 0, sizeof(characteristics));
169}
170
171KeyCharacteristics::~KeyCharacteristics() {
172    keymaster_free_characteristics(&characteristics);
173}
174
175void KeyCharacteristics::readFromParcel(const Parcel& in) {
176    size_t length = 0;
177    keymaster_key_param_t* params = readParamList(in, &length);
178    characteristics.sw_enforced.params = params;
179    characteristics.sw_enforced.length = length;
180
181    params = readParamList(in, &length);
182    characteristics.hw_enforced.params = params;
183    characteristics.hw_enforced.length = length;
184}
185
186void KeyCharacteristics::writeToParcel(Parcel* out) const {
187    if (characteristics.sw_enforced.params) {
188        out->writeInt32(characteristics.sw_enforced.length);
189        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
190            out->writeInt32(1);
191            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
192        }
193    } else {
194        out->writeInt32(0);
195    }
196    if (characteristics.hw_enforced.params) {
197        out->writeInt32(characteristics.hw_enforced.length);
198        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
199            out->writeInt32(1);
200            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
201        }
202    } else {
203        out->writeInt32(0);
204    }
205}
206
207void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
208    switch (keymaster_tag_get_type(param.tag)) {
209        case KM_ENUM:
210        case KM_ENUM_REP: {
211            out->writeInt32(param.tag);
212            out->writeInt32(param.enumerated);
213            break;
214        }
215        case KM_INT:
216        case KM_INT_REP: {
217            out->writeInt32(param.tag);
218            out->writeInt32(param.integer);
219            break;
220        }
221        case KM_LONG: {
222            out->writeInt32(param.tag);
223            out->writeInt64(param.long_integer);
224            break;
225        }
226        case KM_DATE: {
227            out->writeInt32(param.tag);
228            out->writeInt64(param.date_time);
229            break;
230        }
231        case KM_BOOL: {
232            out->writeInt32(param.tag);
233            break;
234        }
235        case KM_BIGNUM:
236        case KM_BYTES: {
237            out->writeInt32(param.tag);
238            out->writeInt32(param.blob.data_length);
239            void* buf = out->writeInplace(param.blob.data_length);
240            if (buf) {
241                memcpy(buf, param.blob.data, param.blob.data_length);
242            } else {
243                ALOGE("Failed to writeInplace keymaster blob param");
244            }
245            break;
246        }
247        default: {
248            ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
249        }
250    }
251}
252
253
254bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
255    if (in.readInt32() == 0) {
256        return false;
257    }
258    keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
259    switch (keymaster_tag_get_type(tag)) {
260        case KM_ENUM:
261        case KM_ENUM_REP: {
262            uint32_t value = in.readInt32();
263            *out = keymaster_param_enum(tag, value);
264            break;
265        }
266        case KM_INT:
267        case KM_INT_REP: {
268            uint32_t value = in.readInt32();
269            *out = keymaster_param_int(tag, value);
270            break;
271        }
272        case KM_LONG: {
273            uint64_t value = in.readInt64();
274            *out = keymaster_param_long(tag, value);
275            break;
276        }
277        case KM_DATE: {
278            uint64_t value = in.readInt64();
279            *out = keymaster_param_date(tag, value);
280            break;
281        }
282        case KM_BOOL: {
283            *out = keymaster_param_bool(tag);
284            break;
285        }
286        case KM_BIGNUM:
287        case KM_BYTES: {
288            ssize_t length = in.readInt32();
289            uint8_t* data = NULL;
290            size_t ulength = 0;
291            if (length >= 0) {
292                ulength = (size_t) length;
293                // use malloc here so we can use keymaster_free_param_values
294                // consistently.
295                data = reinterpret_cast<uint8_t*>(malloc(ulength));
296                const void* buf = in.readInplace(ulength);
297                if (!buf || !data) {
298                    ALOGE("Failed to allocate buffer for keymaster blob param");
299                    return false;
300                }
301                memcpy(data, buf, ulength);
302            }
303            *out = keymaster_param_blob(tag, data, ulength);
304            break;
305        }
306        default: {
307            ALOGE("Unsupported keymaster_tag_t %d", tag);
308            return false;
309        }
310    }
311    return true;
312}
313
314/**
315 * Read a byte array from in. The data at *data is still owned by the parcel
316 */
317static void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) {
318    ssize_t slength = in.readInt32();
319    if (slength > 0) {
320        *data = reinterpret_cast<const uint8_t*>(in.readInplace(slength));
321        if (*data) {
322            *length = static_cast<size_t>(slength);
323        } else {
324            *length = 0;
325        }
326    } else {
327        *data = NULL;
328        *length = 0;
329    }
330}
331
332// Read a keymaster_key_param_t* from a Parcel for use in a
333// keymaster_key_characteristics_t. This will be free'd by calling
334// keymaster_free_key_characteristics.
335static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
336    ssize_t slength = in.readInt32();
337    *length = 0;
338    if (slength < 0) {
339        return NULL;
340    }
341    *length = (size_t) slength;
342    if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
343        return NULL;
344    }
345    keymaster_key_param_t* list =
346            reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
347                                                            sizeof(keymaster_key_param_t)));
348    if (!list) {
349        ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
350        goto err;
351    }
352    for (size_t i = 0; i < *length ; i++) {
353        if (!readKeymasterArgumentFromParcel(in, &list[i])) {
354            ALOGE("Failed to read keymaster argument");
355            keymaster_free_param_values(list, i);
356            goto err;
357        }
358    }
359    return list;
360err:
361    free(list);
362    return NULL;
363}
364
365static std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
366    std::unique_ptr<keymaster_blob_t> blob;
367    if (in.readInt32() != 1) {
368        blob.reset(NULL);
369        return blob;
370    }
371    ssize_t length = in.readInt32();
372    blob.reset(new keymaster_blob_t);
373    if (length > 0) {
374        blob->data = reinterpret_cast<const uint8_t*>(in.readInplace(length));
375        if (blob->data) {
376            blob->data_length = static_cast<size_t>(length);
377        } else {
378            blob->data_length = 0;
379        }
380    } else {
381        blob->data = NULL;
382        blob->data_length = 0;
383    }
384    return blob;
385}
386
387class BpKeystoreService: public BpInterface<IKeystoreService>
388{
389public:
390    BpKeystoreService(const sp<IBinder>& impl)
391        : BpInterface<IKeystoreService>(impl)
392    {
393    }
394
395    // test ping
396    virtual int32_t test()
397    {
398        Parcel data, reply;
399        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
400        status_t status = remote()->transact(BnKeystoreService::TEST, data, &reply);
401        if (status != NO_ERROR) {
402            ALOGD("test() could not contact remote: %d\n", status);
403            return -1;
404        }
405        int32_t err = reply.readExceptionCode();
406        int32_t ret = reply.readInt32();
407        if (err < 0) {
408            ALOGD("test() caught exception %d\n", err);
409            return -1;
410        }
411        return ret;
412    }
413
414    virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
415    {
416        Parcel data, reply;
417        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
418        data.writeString16(name);
419        status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
420        if (status != NO_ERROR) {
421            ALOGD("get() could not contact remote: %d\n", status);
422            return -1;
423        }
424        int32_t err = reply.readExceptionCode();
425        ssize_t len = reply.readInt32();
426        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
427            size_t ulen = (size_t) len;
428            const void* buf = reply.readInplace(ulen);
429            *item = (uint8_t*) malloc(ulen);
430            if (*item != NULL) {
431                memcpy(*item, buf, ulen);
432                *itemLength = ulen;
433            } else {
434                ALOGE("out of memory allocating output array in get");
435                *itemLength = 0;
436            }
437        } else {
438            *itemLength = 0;
439        }
440        if (err < 0) {
441            ALOGD("get() caught exception %d\n", err);
442            return -1;
443        }
444        return 0;
445    }
446
447    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
448            int32_t flags)
449    {
450        Parcel data, reply;
451        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
452        data.writeString16(name);
453        data.writeInt32(itemLength);
454        void* buf = data.writeInplace(itemLength);
455        memcpy(buf, item, itemLength);
456        data.writeInt32(uid);
457        data.writeInt32(flags);
458        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
459        if (status != NO_ERROR) {
460            ALOGD("import() could not contact remote: %d\n", status);
461            return -1;
462        }
463        int32_t err = reply.readExceptionCode();
464        int32_t ret = reply.readInt32();
465        if (err < 0) {
466            ALOGD("import() caught exception %d\n", err);
467            return -1;
468        }
469        return ret;
470    }
471
472    virtual int32_t del(const String16& name, int uid)
473    {
474        Parcel data, reply;
475        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
476        data.writeString16(name);
477        data.writeInt32(uid);
478        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
479        if (status != NO_ERROR) {
480            ALOGD("del() could not contact remote: %d\n", status);
481            return -1;
482        }
483        int32_t err = reply.readExceptionCode();
484        int32_t ret = reply.readInt32();
485        if (err < 0) {
486            ALOGD("del() caught exception %d\n", err);
487            return -1;
488        }
489        return ret;
490    }
491
492    virtual int32_t exist(const String16& name, int uid)
493    {
494        Parcel data, reply;
495        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
496        data.writeString16(name);
497        data.writeInt32(uid);
498        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
499        if (status != NO_ERROR) {
500            ALOGD("exist() could not contact remote: %d\n", status);
501            return -1;
502        }
503        int32_t err = reply.readExceptionCode();
504        int32_t ret = reply.readInt32();
505        if (err < 0) {
506            ALOGD("exist() caught exception %d\n", err);
507            return -1;
508        }
509        return ret;
510    }
511
512    virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches)
513    {
514        Parcel data, reply;
515        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
516        data.writeString16(name);
517        data.writeInt32(uid);
518        status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
519        if (status != NO_ERROR) {
520            ALOGD("saw() could not contact remote: %d\n", status);
521            return -1;
522        }
523        int32_t err = reply.readExceptionCode();
524        int32_t numMatches = reply.readInt32();
525        for (int32_t i = 0; i < numMatches; i++) {
526            matches->push(reply.readString16());
527        }
528        int32_t ret = reply.readInt32();
529        if (err < 0) {
530            ALOGD("saw() caught exception %d\n", err);
531            return -1;
532        }
533        return ret;
534    }
535
536    virtual int32_t reset()
537    {
538        Parcel data, reply;
539        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
540        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
541        if (status != NO_ERROR) {
542            ALOGD("reset() could not contact remote: %d\n", status);
543            return -1;
544        }
545        int32_t err = reply.readExceptionCode();
546        int32_t ret = reply.readInt32();
547        if (err < 0) {
548            ALOGD("reset() caught exception %d\n", err);
549            return -1;
550        }
551        return ret;
552    }
553
554    virtual int32_t password(const String16& password)
555    {
556        Parcel data, reply;
557        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
558        data.writeString16(password);
559        status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
560        if (status != NO_ERROR) {
561            ALOGD("password() could not contact remote: %d\n", status);
562            return -1;
563        }
564        int32_t err = reply.readExceptionCode();
565        int32_t ret = reply.readInt32();
566        if (err < 0) {
567            ALOGD("password() caught exception %d\n", err);
568            return -1;
569        }
570        return ret;
571    }
572
573    virtual int32_t lock()
574    {
575        Parcel data, reply;
576        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
577        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
578        if (status != NO_ERROR) {
579            ALOGD("lock() could not contact remote: %d\n", status);
580            return -1;
581        }
582        int32_t err = reply.readExceptionCode();
583        int32_t ret = reply.readInt32();
584        if (err < 0) {
585            ALOGD("lock() caught exception %d\n", err);
586            return -1;
587        }
588        return ret;
589    }
590
591    virtual int32_t unlock(const String16& password)
592    {
593        Parcel data, reply;
594        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
595        data.writeString16(password);
596        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
597        if (status != NO_ERROR) {
598            ALOGD("unlock() could not contact remote: %d\n", status);
599            return -1;
600        }
601        int32_t err = reply.readExceptionCode();
602        int32_t ret = reply.readInt32();
603        if (err < 0) {
604            ALOGD("unlock() caught exception %d\n", err);
605            return -1;
606        }
607        return ret;
608    }
609
610    virtual int32_t zero()
611    {
612        Parcel data, reply;
613        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
614        status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
615        if (status != NO_ERROR) {
616            ALOGD("zero() could not contact remote: %d\n", status);
617            return -1;
618        }
619        int32_t err = reply.readExceptionCode();
620        int32_t ret = reply.readInt32();
621        if (err < 0) {
622            ALOGD("zero() caught exception %d\n", err);
623            return -1;
624        }
625        return ret;
626    }
627
628    virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
629            int32_t flags, Vector<sp<KeystoreArg> >* args)
630    {
631        Parcel data, reply;
632        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
633        data.writeString16(name);
634        data.writeInt32(uid);
635        data.writeInt32(keyType);
636        data.writeInt32(keySize);
637        data.writeInt32(flags);
638        data.writeInt32(1);
639        data.writeInt32(args->size());
640        for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
641            sp<KeystoreArg> item = *it;
642            size_t keyLength = item->size();
643            data.writeInt32(keyLength);
644            void* buf = data.writeInplace(keyLength);
645            memcpy(buf, item->data(), keyLength);
646        }
647        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
648        if (status != NO_ERROR) {
649            ALOGD("generate() could not contact remote: %d\n", status);
650            return -1;
651        }
652        int32_t err = reply.readExceptionCode();
653        int32_t ret = reply.readInt32();
654        if (err < 0) {
655            ALOGD("generate() caught exception %d\n", err);
656            return -1;
657        }
658        return ret;
659    }
660
661    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
662            int flags)
663    {
664        Parcel data, reply;
665        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
666        data.writeString16(name);
667        data.writeInt32(keyLength);
668        void* buf = data.writeInplace(keyLength);
669        memcpy(buf, key, keyLength);
670        data.writeInt32(uid);
671        data.writeInt32(flags);
672        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
673        if (status != NO_ERROR) {
674            ALOGD("import() could not contact remote: %d\n", status);
675            return -1;
676        }
677        int32_t err = reply.readExceptionCode();
678        int32_t ret = reply.readInt32();
679        if (err < 0) {
680            ALOGD("import() caught exception %d\n", err);
681            return -1;
682        }
683        return ret;
684    }
685
686    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
687            size_t* outLength)
688    {
689        Parcel data, reply;
690        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
691        data.writeString16(name);
692        data.writeInt32(inLength);
693        void* buf = data.writeInplace(inLength);
694        memcpy(buf, in, inLength);
695        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
696        if (status != NO_ERROR) {
697            ALOGD("import() could not contact remote: %d\n", status);
698            return -1;
699        }
700        int32_t err = reply.readExceptionCode();
701        ssize_t len = reply.readInt32();
702        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
703            size_t ulen = (size_t) len;
704            const void* outBuf = reply.readInplace(ulen);
705            *out = (uint8_t*) malloc(ulen);
706            if (*out != NULL) {
707                memcpy((void*) *out, outBuf, ulen);
708                *outLength = ulen;
709            } else {
710                ALOGE("out of memory allocating output array in sign");
711                *outLength = 0;
712            }
713        } else {
714            *outLength = 0;
715        }
716        if (err < 0) {
717            ALOGD("import() caught exception %d\n", err);
718            return -1;
719        }
720        return 0;
721    }
722
723    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
724            const uint8_t* signature, size_t signatureLength)
725    {
726        Parcel data, reply;
727        void* buf;
728
729        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
730        data.writeString16(name);
731        data.writeInt32(inLength);
732        buf = data.writeInplace(inLength);
733        memcpy(buf, in, inLength);
734        data.writeInt32(signatureLength);
735        buf = data.writeInplace(signatureLength);
736        memcpy(buf, signature, signatureLength);
737        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
738        if (status != NO_ERROR) {
739            ALOGD("verify() could not contact remote: %d\n", status);
740            return -1;
741        }
742        int32_t err = reply.readExceptionCode();
743        int32_t ret = reply.readInt32();
744        if (err < 0) {
745            ALOGD("verify() caught exception %d\n", err);
746            return -1;
747        }
748        return ret;
749    }
750
751    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
752    {
753        Parcel data, reply;
754        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
755        data.writeString16(name);
756        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
757        if (status != NO_ERROR) {
758            ALOGD("get_pubkey() could not contact remote: %d\n", status);
759            return -1;
760        }
761        int32_t err = reply.readExceptionCode();
762        ssize_t len = reply.readInt32();
763        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
764            size_t ulen = (size_t) len;
765            const void* buf = reply.readInplace(ulen);
766            *pubkey = (uint8_t*) malloc(ulen);
767            if (*pubkey != NULL) {
768                memcpy(*pubkey, buf, ulen);
769                *pubkeyLength = ulen;
770            } else {
771                ALOGE("out of memory allocating output array in get_pubkey");
772                *pubkeyLength = 0;
773            }
774        } else {
775            *pubkeyLength = 0;
776        }
777        if (err < 0) {
778            ALOGD("get_pubkey() caught exception %d\n", err);
779            return -1;
780        }
781        return 0;
782     }
783
784    virtual int32_t del_key(const String16& name, int uid)
785    {
786        Parcel data, reply;
787        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
788        data.writeString16(name);
789        data.writeInt32(uid);
790        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
791        if (status != NO_ERROR) {
792            ALOGD("del_key() could not contact remote: %d\n", status);
793            return -1;
794        }
795        int32_t err = reply.readExceptionCode();
796        int32_t ret = reply.readInt32();
797        if (err < 0) {
798            ALOGD("del_key() caught exception %d\n", err);
799            return -1;
800        }
801        return ret;
802    }
803
804    virtual int32_t grant(const String16& name, int32_t granteeUid)
805    {
806        Parcel data, reply;
807        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
808        data.writeString16(name);
809        data.writeInt32(granteeUid);
810        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
811        if (status != NO_ERROR) {
812            ALOGD("grant() could not contact remote: %d\n", status);
813            return -1;
814        }
815        int32_t err = reply.readExceptionCode();
816        int32_t ret = reply.readInt32();
817        if (err < 0) {
818            ALOGD("grant() caught exception %d\n", err);
819            return -1;
820        }
821        return ret;
822    }
823
824    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
825    {
826        Parcel data, reply;
827        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
828        data.writeString16(name);
829        data.writeInt32(granteeUid);
830        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
831        if (status != NO_ERROR) {
832            ALOGD("ungrant() could not contact remote: %d\n", status);
833            return -1;
834        }
835        int32_t err = reply.readExceptionCode();
836        int32_t ret = reply.readInt32();
837        if (err < 0) {
838            ALOGD("ungrant() caught exception %d\n", err);
839            return -1;
840        }
841        return ret;
842    }
843
844    int64_t getmtime(const String16& name)
845    {
846        Parcel data, reply;
847        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
848        data.writeString16(name);
849        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
850        if (status != NO_ERROR) {
851            ALOGD("getmtime() could not contact remote: %d\n", status);
852            return -1;
853        }
854        int32_t err = reply.readExceptionCode();
855        int64_t ret = reply.readInt64();
856        if (err < 0) {
857            ALOGD("getmtime() caught exception %d\n", err);
858            return -1;
859        }
860        return ret;
861    }
862
863    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
864            int32_t destUid)
865    {
866        Parcel data, reply;
867        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
868        data.writeString16(srcKey);
869        data.writeInt32(srcUid);
870        data.writeString16(destKey);
871        data.writeInt32(destUid);
872        status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
873        if (status != NO_ERROR) {
874            ALOGD("duplicate() could not contact remote: %d\n", status);
875            return -1;
876        }
877        int32_t err = reply.readExceptionCode();
878        int32_t ret = reply.readInt32();
879        if (err < 0) {
880            ALOGD("duplicate() caught exception %d\n", err);
881            return -1;
882        }
883        return ret;
884    }
885
886    virtual int32_t is_hardware_backed(const String16& keyType)
887    {
888        Parcel data, reply;
889        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
890        data.writeString16(keyType);
891        status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
892        if (status != NO_ERROR) {
893            ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
894            return -1;
895        }
896        int32_t err = reply.readExceptionCode();
897        int32_t ret = reply.readInt32();
898        if (err < 0) {
899            ALOGD("is_hardware_backed() caught exception %d\n", err);
900            return -1;
901        }
902        return ret;
903    }
904
905    virtual int32_t clear_uid(int64_t uid)
906    {
907        Parcel data, reply;
908        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
909        data.writeInt64(uid);
910        status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
911        if (status != NO_ERROR) {
912            ALOGD("clear_uid() could not contact remote: %d\n", status);
913            return -1;
914        }
915        int32_t err = reply.readExceptionCode();
916        int32_t ret = reply.readInt32();
917        if (err < 0) {
918            ALOGD("clear_uid() caught exception %d\n", err);
919            return -1;
920        }
921        return ret;
922    }
923
924    virtual int32_t reset_uid(int32_t uid) {
925        Parcel data, reply;
926        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
927        data.writeInt32(uid);
928        status_t status = remote()->transact(BnKeystoreService::RESET_UID, data, &reply);
929        if (status != NO_ERROR) {
930            ALOGD("reset_uid() could not contact remote: %d\n", status);
931            return -1;
932        }
933        int32_t err = reply.readExceptionCode();
934        int32_t ret = reply.readInt32();
935        if (err < 0) {
936            ALOGD("reset_uid() caught exception %d\n", err);
937            return -1;
938        }
939        return ret;
940
941    }
942
943    virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid)
944    {
945        Parcel data, reply;
946        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
947        data.writeInt32(sourceUid);
948        data.writeInt32(targetUid);
949        status_t status = remote()->transact(BnKeystoreService::SYNC_UID, data, &reply);
950        if (status != NO_ERROR) {
951            ALOGD("sync_uid() could not contact remote: %d\n", status);
952            return -1;
953        }
954        int32_t err = reply.readExceptionCode();
955        int32_t ret = reply.readInt32();
956        if (err < 0) {
957            ALOGD("sync_uid() caught exception %d\n", err);
958            return -1;
959        }
960        return ret;
961    }
962
963    virtual int32_t password_uid(const String16& password, int32_t uid)
964    {
965        Parcel data, reply;
966        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
967        data.writeString16(password);
968        data.writeInt32(uid);
969        status_t status = remote()->transact(BnKeystoreService::PASSWORD_UID, data, &reply);
970        if (status != NO_ERROR) {
971            ALOGD("password_uid() could not contact remote: %d\n", status);
972            return -1;
973        }
974        int32_t err = reply.readExceptionCode();
975        int32_t ret = reply.readInt32();
976        if (err < 0) {
977            ALOGD("password_uid() caught exception %d\n", err);
978            return -1;
979        }
980        return ret;
981    }
982    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
983    {
984        Parcel data, reply;
985        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
986        data.writeInt32(bufLength);
987        data.writeByteArray(bufLength, buf);
988        status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
989        if (status != NO_ERROR) {
990            ALOGD("addRngEntropy() could not contact remote: %d\n", status);
991            return -1;
992        }
993        int32_t err = reply.readExceptionCode();
994        int32_t ret = reply.readInt32();
995        if (err < 0) {
996            ALOGD("addRngEntropy() caught exception %d\n", err);
997            return -1;
998        }
999        return ret;
1000    };
1001
1002    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
1003                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
1004                                KeyCharacteristics* outCharacteristics)
1005    {
1006        Parcel data, reply;
1007        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1008        data.writeString16(name);
1009        data.writeInt32(1);
1010        params.writeToParcel(&data);
1011        data.writeByteArray(entropyLength, entropy);
1012        data.writeInt32(uid);
1013        data.writeInt32(flags);
1014        status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
1015        if (status != NO_ERROR) {
1016            ALOGD("generateKey() could not contact remote: %d\n", status);
1017            return KM_ERROR_UNKNOWN_ERROR;
1018        }
1019        int32_t err = reply.readExceptionCode();
1020        int32_t ret = reply.readInt32();
1021        if (err < 0) {
1022            ALOGD("generateKey() caught exception %d\n", err);
1023            return KM_ERROR_UNKNOWN_ERROR;
1024        }
1025        if (reply.readInt32() != 0 && outCharacteristics) {
1026            outCharacteristics->readFromParcel(reply);
1027        }
1028        return ret;
1029    }
1030    virtual int32_t getKeyCharacteristics(const String16& name,
1031                                          const keymaster_blob_t* clientId,
1032                                          const keymaster_blob_t* appData,
1033                                          KeyCharacteristics* outCharacteristics)
1034    {
1035        Parcel data, reply;
1036        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1037        data.writeString16(name);
1038        if (clientId) {
1039            data.writeByteArray(clientId->data_length, clientId->data);
1040        } else {
1041            data.writeInt32(-1);
1042        }
1043        if (appData) {
1044            data.writeByteArray(appData->data_length, appData->data);
1045        } else {
1046            data.writeInt32(-1);
1047        }
1048        status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
1049                                             data, &reply);
1050        if (status != NO_ERROR) {
1051            ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
1052            return KM_ERROR_UNKNOWN_ERROR;
1053        }
1054        int32_t err = reply.readExceptionCode();
1055        int32_t ret = reply.readInt32();
1056        if (err < 0) {
1057            ALOGD("getKeyCharacteristics() caught exception %d\n", err);
1058            return KM_ERROR_UNKNOWN_ERROR;
1059        }
1060        if (reply.readInt32() != 0 && outCharacteristics) {
1061            outCharacteristics->readFromParcel(reply);
1062        }
1063        return ret;
1064    }
1065    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
1066                              keymaster_key_format_t format, const uint8_t *keyData,
1067                              size_t keyLength, int uid, int flags,
1068                              KeyCharacteristics* outCharacteristics)
1069    {
1070        Parcel data, reply;
1071        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1072        data.writeString16(name);
1073        data.writeInt32(1);
1074        params.writeToParcel(&data);
1075        data.writeInt32(format);
1076        data.writeByteArray(keyLength, keyData);
1077        data.writeInt32(uid);
1078        data.writeInt32(flags);
1079        status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
1080        if (status != NO_ERROR) {
1081            ALOGD("importKey() could not contact remote: %d\n", status);
1082            return KM_ERROR_UNKNOWN_ERROR;
1083        }
1084        int32_t err = reply.readExceptionCode();
1085        int32_t ret = reply.readInt32();
1086        if (err < 0) {
1087            ALOGD("importKey() caught exception %d\n", err);
1088            return KM_ERROR_UNKNOWN_ERROR;
1089        }
1090        if (reply.readInt32() != 0 && outCharacteristics) {
1091            outCharacteristics->readFromParcel(reply);
1092        }
1093        return ret;
1094    }
1095
1096    virtual void exportKey(const String16& name, keymaster_key_format_t format,
1097                           const keymaster_blob_t* clientId,
1098                           const keymaster_blob_t* appData, ExportResult* result)
1099    {
1100        if (!result) {
1101            return;
1102        }
1103
1104        Parcel data, reply;
1105        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1106        data.writeString16(name);
1107        data.writeInt32(format);
1108        if (clientId) {
1109            data.writeByteArray(clientId->data_length, clientId->data);
1110        } else {
1111            data.writeInt32(-1);
1112        }
1113        if (appData) {
1114            data.writeByteArray(appData->data_length, appData->data);
1115        } else {
1116            data.writeInt32(-1);
1117        }
1118        status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
1119        if (status != NO_ERROR) {
1120            ALOGD("exportKey() could not contact remote: %d\n", status);
1121            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1122            return;
1123        }
1124        int32_t err = reply.readExceptionCode();
1125        if (err < 0) {
1126            ALOGD("exportKey() caught exception %d\n", err);
1127            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1128            return;
1129        }
1130        if (reply.readInt32() != 0) {
1131            result->readFromParcel(reply);
1132        }
1133    }
1134
1135    virtual void begin(const sp<IBinder>& appToken, const String16& name,
1136                       keymaster_purpose_t purpose, bool pruneable,
1137                       const KeymasterArguments& params, const uint8_t* entropy,
1138                       size_t entropyLength, KeymasterArguments* outParams,
1139                       OperationResult* result)
1140    {
1141        if (!result || !outParams) {
1142            return;
1143        }
1144        Parcel data, reply;
1145        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1146        data.writeStrongBinder(appToken);
1147        data.writeString16(name);
1148        data.writeInt32(purpose);
1149        data.writeInt32(pruneable ? 1 : 0);
1150        data.writeInt32(1);
1151        params.writeToParcel(&data);
1152        data.writeByteArray(entropyLength, entropy);
1153        status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
1154        if (status != NO_ERROR) {
1155            ALOGD("begin() could not contact remote: %d\n", status);
1156            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1157            return;
1158        }
1159        int32_t err = reply.readExceptionCode();
1160        if (err < 0) {
1161            ALOGD("begin() caught exception %d\n", err);
1162            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1163            return;
1164        }
1165        if (reply.readInt32() != 0) {
1166            result->readFromParcel(reply);
1167        }
1168        if (reply.readInt32() != 0) {
1169            outParams->readFromParcel(reply);
1170        }
1171    }
1172
1173    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
1174                        const uint8_t* opData, size_t dataLength, OperationResult* result)
1175    {
1176        if (!result) {
1177            return;
1178        }
1179        Parcel data, reply;
1180        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1181        data.writeStrongBinder(token);
1182        data.writeInt32(1);
1183        params.writeToParcel(&data);
1184        data.writeByteArray(dataLength, opData);
1185        status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
1186        if (status != NO_ERROR) {
1187            ALOGD("update() could not contact remote: %d\n", status);
1188            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1189            return;
1190        }
1191        int32_t err = reply.readExceptionCode();
1192        if (err < 0) {
1193            ALOGD("update() caught exception %d\n", err);
1194            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1195            return;
1196        }
1197        if (reply.readInt32() != 0) {
1198            result->readFromParcel(reply);
1199        }
1200    }
1201
1202    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
1203                        const uint8_t* signature, size_t signatureLength, OperationResult* result)
1204    {
1205        if (!result) {
1206            return;
1207        }
1208        Parcel data, reply;
1209        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1210        data.writeStrongBinder(token);
1211        data.writeInt32(1);
1212        params.writeToParcel(&data);
1213        data.writeByteArray(signatureLength, signature);
1214        status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
1215        if (status != NO_ERROR) {
1216            ALOGD("finish() could not contact remote: %d\n", status);
1217            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1218            return;
1219        }
1220        int32_t err = reply.readExceptionCode();
1221        if (err < 0) {
1222            ALOGD("finish() caught exception %d\n", err);
1223            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1224            return;
1225        }
1226        if (reply.readInt32() != 0) {
1227            result->readFromParcel(reply);
1228        }
1229    }
1230
1231    virtual int32_t abort(const sp<IBinder>& token)
1232    {
1233        Parcel data, reply;
1234        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1235        data.writeStrongBinder(token);
1236        status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
1237        if (status != NO_ERROR) {
1238            ALOGD("abort() could not contact remote: %d\n", status);
1239            return KM_ERROR_UNKNOWN_ERROR;
1240        }
1241        int32_t err = reply.readExceptionCode();
1242        int32_t ret = reply.readInt32();
1243        if (err < 0) {
1244            ALOGD("abort() caught exception %d\n", err);
1245            return KM_ERROR_UNKNOWN_ERROR;
1246        }
1247        return ret;
1248    }
1249};
1250
1251IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
1252
1253// ----------------------------------------------------------------------
1254
1255status_t BnKeystoreService::onTransact(
1256    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1257{
1258    switch(code) {
1259        case TEST: {
1260            CHECK_INTERFACE(IKeystoreService, data, reply);
1261            int32_t ret = test();
1262            reply->writeNoException();
1263            reply->writeInt32(ret);
1264            return NO_ERROR;
1265        } break;
1266        case GET: {
1267            CHECK_INTERFACE(IKeystoreService, data, reply);
1268            String16 name = data.readString16();
1269            void* out = NULL;
1270            size_t outSize = 0;
1271            int32_t ret = get(name, (uint8_t**) &out, &outSize);
1272            reply->writeNoException();
1273            if (ret == 1) {
1274                reply->writeInt32(outSize);
1275                void* buf = reply->writeInplace(outSize);
1276                memcpy(buf, out, outSize);
1277                free(out);
1278            } else {
1279                reply->writeInt32(-1);
1280            }
1281            return NO_ERROR;
1282        } break;
1283        case INSERT: {
1284            CHECK_INTERFACE(IKeystoreService, data, reply);
1285            String16 name = data.readString16();
1286            ssize_t inSize = data.readInt32();
1287            const void* in;
1288            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1289                in = data.readInplace(inSize);
1290            } else {
1291                in = NULL;
1292                inSize = 0;
1293            }
1294            int uid = data.readInt32();
1295            int32_t flags = data.readInt32();
1296            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
1297            reply->writeNoException();
1298            reply->writeInt32(ret);
1299            return NO_ERROR;
1300        } break;
1301        case DEL: {
1302            CHECK_INTERFACE(IKeystoreService, data, reply);
1303            String16 name = data.readString16();
1304            int uid = data.readInt32();
1305            int32_t ret = del(name, uid);
1306            reply->writeNoException();
1307            reply->writeInt32(ret);
1308            return NO_ERROR;
1309        } break;
1310        case EXIST: {
1311            CHECK_INTERFACE(IKeystoreService, data, reply);
1312            String16 name = data.readString16();
1313            int uid = data.readInt32();
1314            int32_t ret = exist(name, uid);
1315            reply->writeNoException();
1316            reply->writeInt32(ret);
1317            return NO_ERROR;
1318        } break;
1319        case SAW: {
1320            CHECK_INTERFACE(IKeystoreService, data, reply);
1321            String16 name = data.readString16();
1322            int uid = data.readInt32();
1323            Vector<String16> matches;
1324            int32_t ret = saw(name, uid, &matches);
1325            reply->writeNoException();
1326            reply->writeInt32(matches.size());
1327            Vector<String16>::const_iterator it = matches.begin();
1328            for (; it != matches.end(); ++it) {
1329                reply->writeString16(*it);
1330            }
1331            reply->writeInt32(ret);
1332            return NO_ERROR;
1333        } break;
1334        case RESET: {
1335            CHECK_INTERFACE(IKeystoreService, data, reply);
1336            int32_t ret = reset();
1337            reply->writeNoException();
1338            reply->writeInt32(ret);
1339            return NO_ERROR;
1340        } break;
1341        case PASSWORD: {
1342            CHECK_INTERFACE(IKeystoreService, data, reply);
1343            String16 pass = data.readString16();
1344            int32_t ret = password(pass);
1345            reply->writeNoException();
1346            reply->writeInt32(ret);
1347            return NO_ERROR;
1348        } break;
1349        case LOCK: {
1350            CHECK_INTERFACE(IKeystoreService, data, reply);
1351            int32_t ret = lock();
1352            reply->writeNoException();
1353            reply->writeInt32(ret);
1354            return NO_ERROR;
1355        } break;
1356        case UNLOCK: {
1357            CHECK_INTERFACE(IKeystoreService, data, reply);
1358            String16 pass = data.readString16();
1359            int32_t ret = unlock(pass);
1360            reply->writeNoException();
1361            reply->writeInt32(ret);
1362            return NO_ERROR;
1363        } break;
1364        case ZERO: {
1365            CHECK_INTERFACE(IKeystoreService, data, reply);
1366            int32_t ret = zero();
1367            reply->writeNoException();
1368            reply->writeInt32(ret);
1369            return NO_ERROR;
1370        } break;
1371        case GENERATE: {
1372            CHECK_INTERFACE(IKeystoreService, data, reply);
1373            String16 name = data.readString16();
1374            int32_t uid = data.readInt32();
1375            int32_t keyType = data.readInt32();
1376            int32_t keySize = data.readInt32();
1377            int32_t flags = data.readInt32();
1378            Vector<sp<KeystoreArg> > args;
1379            int32_t argsPresent = data.readInt32();
1380            if (argsPresent == 1) {
1381                ssize_t numArgs = data.readInt32();
1382                if (numArgs > MAX_GENERATE_ARGS) {
1383                    return BAD_VALUE;
1384                }
1385                if (numArgs > 0) {
1386                    for (size_t i = 0; i < (size_t) numArgs; i++) {
1387                        ssize_t inSize = data.readInt32();
1388                        if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1389                            sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize),
1390                                                                  inSize);
1391                            args.push_back(arg);
1392                        } else {
1393                            args.push_back(NULL);
1394                        }
1395                    }
1396                }
1397            }
1398            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
1399            reply->writeNoException();
1400            reply->writeInt32(ret);
1401            return NO_ERROR;
1402        } break;
1403        case IMPORT: {
1404            CHECK_INTERFACE(IKeystoreService, data, reply);
1405            String16 name = data.readString16();
1406            ssize_t inSize = data.readInt32();
1407            const void* in;
1408            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1409                in = data.readInplace(inSize);
1410            } else {
1411                in = NULL;
1412                inSize = 0;
1413            }
1414            int uid = data.readInt32();
1415            int32_t flags = data.readInt32();
1416            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
1417            reply->writeNoException();
1418            reply->writeInt32(ret);
1419            return NO_ERROR;
1420        } break;
1421        case SIGN: {
1422            CHECK_INTERFACE(IKeystoreService, data, reply);
1423            String16 name = data.readString16();
1424            ssize_t inSize = data.readInt32();
1425            const void* in;
1426            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1427                in = data.readInplace(inSize);
1428            } else {
1429                in = NULL;
1430                inSize = 0;
1431            }
1432            void* out = NULL;
1433            size_t outSize = 0;
1434            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
1435            reply->writeNoException();
1436            if (outSize > 0 && out != NULL) {
1437                reply->writeInt32(outSize);
1438                void* buf = reply->writeInplace(outSize);
1439                memcpy(buf, out, outSize);
1440                free(out);
1441            } else {
1442                reply->writeInt32(-1);
1443            }
1444            reply->writeInt32(ret);
1445            return NO_ERROR;
1446        } break;
1447        case VERIFY: {
1448            CHECK_INTERFACE(IKeystoreService, data, reply);
1449            String16 name = data.readString16();
1450            ssize_t inSize = data.readInt32();
1451            const void* in;
1452            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1453                in = data.readInplace(inSize);
1454            } else {
1455                in = NULL;
1456                inSize = 0;
1457            }
1458            ssize_t sigSize = data.readInt32();
1459            const void* sig;
1460            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
1461                sig = data.readInplace(sigSize);
1462            } else {
1463                sig = NULL;
1464                sigSize = 0;
1465            }
1466            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
1467                    (size_t) sigSize);
1468            reply->writeNoException();
1469            reply->writeInt32(ret ? 1 : 0);
1470            return NO_ERROR;
1471        } break;
1472        case GET_PUBKEY: {
1473            CHECK_INTERFACE(IKeystoreService, data, reply);
1474            String16 name = data.readString16();
1475            void* out = NULL;
1476            size_t outSize = 0;
1477            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
1478            reply->writeNoException();
1479            if (outSize > 0 && out != NULL) {
1480                reply->writeInt32(outSize);
1481                void* buf = reply->writeInplace(outSize);
1482                memcpy(buf, out, outSize);
1483                free(out);
1484            } else {
1485                reply->writeInt32(-1);
1486            }
1487            reply->writeInt32(ret);
1488            return NO_ERROR;
1489        } break;
1490        case DEL_KEY: {
1491            CHECK_INTERFACE(IKeystoreService, data, reply);
1492            String16 name = data.readString16();
1493            int uid = data.readInt32();
1494            int32_t ret = del_key(name, uid);
1495            reply->writeNoException();
1496            reply->writeInt32(ret);
1497            return NO_ERROR;
1498        } break;
1499        case GRANT: {
1500            CHECK_INTERFACE(IKeystoreService, data, reply);
1501            String16 name = data.readString16();
1502            int32_t granteeUid = data.readInt32();
1503            int32_t ret = grant(name, granteeUid);
1504            reply->writeNoException();
1505            reply->writeInt32(ret);
1506            return NO_ERROR;
1507        } break;
1508        case UNGRANT: {
1509            CHECK_INTERFACE(IKeystoreService, data, reply);
1510            String16 name = data.readString16();
1511            int32_t granteeUid = data.readInt32();
1512            int32_t ret = ungrant(name, granteeUid);
1513            reply->writeNoException();
1514            reply->writeInt32(ret);
1515            return NO_ERROR;
1516        } break;
1517        case GETMTIME: {
1518            CHECK_INTERFACE(IKeystoreService, data, reply);
1519            String16 name = data.readString16();
1520            int64_t ret = getmtime(name);
1521            reply->writeNoException();
1522            reply->writeInt64(ret);
1523            return NO_ERROR;
1524        } break;
1525        case DUPLICATE: {
1526            CHECK_INTERFACE(IKeystoreService, data, reply);
1527            String16 srcKey = data.readString16();
1528            int32_t srcUid = data.readInt32();
1529            String16 destKey = data.readString16();
1530            int32_t destUid = data.readInt32();
1531            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
1532            reply->writeNoException();
1533            reply->writeInt32(ret);
1534            return NO_ERROR;
1535        } break;
1536        case IS_HARDWARE_BACKED: {
1537            CHECK_INTERFACE(IKeystoreService, data, reply);
1538            String16 keyType = data.readString16();
1539            int32_t ret = is_hardware_backed(keyType);
1540            reply->writeNoException();
1541            reply->writeInt32(ret);
1542            return NO_ERROR;
1543        }
1544        case CLEAR_UID: {
1545            CHECK_INTERFACE(IKeystoreService, data, reply);
1546            int64_t uid = data.readInt64();
1547            int32_t ret = clear_uid(uid);
1548            reply->writeNoException();
1549            reply->writeInt32(ret);
1550            return NO_ERROR;
1551        }
1552        case RESET_UID: {
1553            CHECK_INTERFACE(IKeystoreService, data, reply);
1554            int32_t uid = data.readInt32();
1555            int32_t ret = reset_uid(uid);
1556            reply->writeNoException();
1557            reply->writeInt32(ret);
1558            return NO_ERROR;
1559        }
1560        case SYNC_UID: {
1561            CHECK_INTERFACE(IKeystoreService, data, reply);
1562            int32_t sourceUid = data.readInt32();
1563            int32_t targetUid = data.readInt32();
1564            int32_t ret = sync_uid(sourceUid, targetUid);
1565            reply->writeNoException();
1566            reply->writeInt32(ret);
1567            return NO_ERROR;
1568        }
1569        case PASSWORD_UID: {
1570            CHECK_INTERFACE(IKeystoreService, data, reply);
1571            String16 password = data.readString16();
1572            int32_t uid = data.readInt32();
1573            int32_t ret = password_uid(password, uid);
1574            reply->writeNoException();
1575            reply->writeInt32(ret);
1576            return NO_ERROR;
1577        }
1578        case ADD_RNG_ENTROPY: {
1579            CHECK_INTERFACE(IKeystoreService, data, reply);
1580            const uint8_t* bytes = NULL;
1581            size_t size = 0;
1582            readByteArray(data, &bytes, &size);
1583            int32_t ret = addRngEntropy(bytes, size);
1584            reply->writeNoException();
1585            reply->writeInt32(ret);
1586            return NO_ERROR;
1587        }
1588        case GENERATE_KEY: {
1589            CHECK_INTERFACE(IKeystoreService, data, reply);
1590            String16 name = data.readString16();
1591            KeymasterArguments args;
1592            if (data.readInt32() != 0) {
1593                args.readFromParcel(data);
1594            }
1595            const uint8_t* entropy = NULL;
1596            size_t entropyLength = 0;
1597            readByteArray(data, &entropy, &entropyLength);
1598            int32_t uid = data.readInt32();
1599            int32_t flags = data.readInt32();
1600            KeyCharacteristics outCharacteristics;
1601            int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
1602                                      &outCharacteristics);
1603            reply->writeNoException();
1604            reply->writeInt32(ret);
1605            reply->writeInt32(1);
1606            outCharacteristics.writeToParcel(reply);
1607            return NO_ERROR;
1608        }
1609        case GET_KEY_CHARACTERISTICS: {
1610            CHECK_INTERFACE(IKeystoreService, data, reply);
1611            String16 name = data.readString16();
1612            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1613            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
1614            KeyCharacteristics outCharacteristics;
1615            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(),
1616                                            &outCharacteristics);
1617            reply->writeNoException();
1618            reply->writeInt32(ret);
1619            reply->writeInt32(1);
1620            outCharacteristics.writeToParcel(reply);
1621            return NO_ERROR;
1622        }
1623        case IMPORT_KEY: {
1624            CHECK_INTERFACE(IKeystoreService, data, reply);
1625            String16 name = data.readString16();
1626            KeymasterArguments args;
1627            if (data.readInt32() != 0) {
1628                args.readFromParcel(data);
1629            }
1630            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
1631            const uint8_t* keyData = NULL;
1632            size_t keyLength = 0;
1633            readByteArray(data, &keyData, &keyLength);
1634            int32_t uid = data.readInt32();
1635            int32_t flags = data.readInt32();
1636            KeyCharacteristics outCharacteristics;
1637            int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
1638                                    &outCharacteristics);
1639            reply->writeNoException();
1640            reply->writeInt32(ret);
1641            reply->writeInt32(1);
1642            outCharacteristics.writeToParcel(reply);
1643
1644            return NO_ERROR;
1645        }
1646        case EXPORT_KEY: {
1647            CHECK_INTERFACE(IKeystoreService, data, reply);
1648            String16 name = data.readString16();
1649            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
1650            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1651            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
1652            ExportResult result;
1653            exportKey(name, format, clientId.get(), appData.get(), &result);
1654            reply->writeNoException();
1655            reply->writeInt32(1);
1656            result.writeToParcel(reply);
1657
1658            return NO_ERROR;
1659        }
1660        case BEGIN: {
1661            CHECK_INTERFACE(IKeystoreService, data, reply);
1662            sp<IBinder> token = data.readStrongBinder();
1663            String16 name = data.readString16();
1664            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
1665            bool pruneable = data.readInt32() != 0;
1666            KeymasterArguments args;
1667            if (data.readInt32() != 0) {
1668                args.readFromParcel(data);
1669            }
1670            const uint8_t* entropy = NULL;
1671            size_t entropyLength = 0;
1672            readByteArray(data, &entropy, &entropyLength);
1673            KeymasterArguments outArgs;
1674            OperationResult result;
1675            begin(token, name, purpose, pruneable, args, entropy, entropyLength, &outArgs,
1676                  &result);
1677            reply->writeNoException();
1678            reply->writeInt32(1);
1679            result.writeToParcel(reply);
1680            reply->writeInt32(1);
1681            outArgs.writeToParcel(reply);
1682
1683            return NO_ERROR;
1684        }
1685        case UPDATE: {
1686            CHECK_INTERFACE(IKeystoreService, data, reply);
1687            sp<IBinder> token = data.readStrongBinder();
1688            KeymasterArguments args;
1689            if (data.readInt32() != 0) {
1690                args.readFromParcel(data);
1691            }
1692            const uint8_t* buf = NULL;
1693            size_t bufLength = 0;
1694            readByteArray(data, &buf, &bufLength);
1695            OperationResult result;
1696            update(token, args, buf, bufLength, &result);
1697            reply->writeNoException();
1698            reply->writeInt32(1);
1699            result.writeToParcel(reply);
1700
1701            return NO_ERROR;
1702        }
1703        case FINISH: {
1704            CHECK_INTERFACE(IKeystoreService, data, reply);
1705            sp<IBinder> token = data.readStrongBinder();
1706            KeymasterArguments args;
1707            if (data.readInt32() != 0) {
1708                args.readFromParcel(data);
1709            }
1710            const uint8_t* buf = NULL;
1711            size_t bufLength = 0;
1712            readByteArray(data, &buf, &bufLength);
1713            OperationResult result;
1714            finish(token, args, buf, bufLength, &result);
1715            reply->writeNoException();
1716            reply->writeInt32(1);
1717            result.writeToParcel(reply);
1718
1719            return NO_ERROR;
1720        }
1721        case ABORT: {
1722            CHECK_INTERFACE(IKeystoreService, data, reply);
1723            sp<IBinder> token = data.readStrongBinder();
1724            int32_t result = abort(token);
1725            reply->writeNoException();
1726            reply->writeInt32(result);
1727
1728            return NO_ERROR;
1729        }
1730        default:
1731            return BBinder::onTransact(code, data, reply, flags);
1732    }
1733}
1734
1735// ----------------------------------------------------------------------------
1736
1737}; // namespace android
1738