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