blob: 29966592b96abf9fe28c8c960d1596a54baecc12 [file] [log] [blame]
Kenny Root07438c82012-11-02 15:41:02 -07001/*
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>
Chad Brubaker9899d6b2015-02-03 13:03:00 -080019#include <sys/limits.h>
Kenny Root07438c82012-11-02 15:41:02 -070020#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
Shawn Willden77d71ca2014-11-12 16:45:12 -070033const ssize_t MAX_GENERATE_ARGS = 3;
Chad Brubaker9899d6b2015-02-03 13:03:00 -080034static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
Shawn Willden77d71ca2014-11-12 16:45:12 -070035
Kenny Root96427ba2013-08-16 14:02:41 -070036KeystoreArg::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
Chad Brubakerc3a18562015-03-17 18:21:35 -070051OperationResult::OperationResult() : resultCode(0), token(), handle(0), inputConsumed(0),
Chad Brubaker9899d6b2015-02-03 13:03:00 -080052 data(NULL), dataLength(0) {
53}
54
55OperationResult::~OperationResult() {
56}
57
Bin Chen9ec92702016-08-25 14:25:05 +100058status_t OperationResult::readFromParcel(const Parcel* inn) {
59 const Parcel& in = *inn;
Chad Brubaker9899d6b2015-02-03 13:03:00 -080060 resultCode = in.readInt32();
61 token = in.readStrongBinder();
Chad Brubakerc3a18562015-03-17 18:21:35 -070062 handle = static_cast<keymaster_operation_handle_t>(in.readInt64());
Chad Brubaker9899d6b2015-02-03 13:03:00 -080063 inputConsumed = in.readInt32();
64 ssize_t length = in.readInt32();
65 dataLength = 0;
66 if (length > 0) {
67 const void* buf = in.readInplace(length);
68 if (buf) {
69 data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
70 if (data.get()) {
71 memcpy(data.get(), buf, length);
72 dataLength = (size_t) length;
73 } else {
74 ALOGE("Failed to allocate OperationResult buffer");
75 }
76 } else {
77 ALOGE("Failed to readInplace OperationResult data");
78 }
79 }
Chad Brubaker57e106d2015-06-01 12:59:00 -070080 outParams.readFromParcel(in);
Bin Chen9ec92702016-08-25 14:25:05 +100081 return OK;
Chad Brubaker9899d6b2015-02-03 13:03:00 -080082}
83
Bin Chen9ec92702016-08-25 14:25:05 +100084status_t OperationResult::writeToParcel(Parcel* out) const {
Chad Brubaker9899d6b2015-02-03 13:03:00 -080085 out->writeInt32(resultCode);
86 out->writeStrongBinder(token);
Chad Brubakerc3a18562015-03-17 18:21:35 -070087 out->writeInt64(handle);
Chad Brubaker9899d6b2015-02-03 13:03:00 -080088 out->writeInt32(inputConsumed);
89 out->writeInt32(dataLength);
90 if (dataLength && data) {
91 void* buf = out->writeInplace(dataLength);
92 if (buf) {
93 memcpy(buf, data.get(), dataLength);
94 } else {
95 ALOGE("Failed to writeInplace OperationResult data.");
96 }
97 }
Chad Brubaker57e106d2015-06-01 12:59:00 -070098 outParams.writeToParcel(out);
Bin Chen9ec92702016-08-25 14:25:05 +100099 return OK;
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800100}
101
102ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
103}
104
105ExportResult::~ExportResult() {
106}
107
Bin Chen96d62712016-08-25 14:41:53 +1000108status_t ExportResult::readFromParcel(const Parcel* inn) {
109 const Parcel& in = *inn;
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800110 resultCode = in.readInt32();
111 ssize_t length = in.readInt32();
112 dataLength = 0;
113 if (length > 0) {
114 const void* buf = in.readInplace(length);
115 if (buf) {
116 exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
117 if (exportData.get()) {
118 memcpy(exportData.get(), buf, length);
119 dataLength = (size_t) length;
120 } else {
121 ALOGE("Failed to allocate ExportData buffer");
122 }
123 } else {
124 ALOGE("Failed to readInplace ExportData data");
125 }
126 }
Bin Chen96d62712016-08-25 14:41:53 +1000127 return OK;
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800128}
129
Bin Chen96d62712016-08-25 14:41:53 +1000130status_t ExportResult::writeToParcel(Parcel* out) const {
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800131 out->writeInt32(resultCode);
132 out->writeInt32(dataLength);
133 if (exportData && dataLength) {
134 void* buf = out->writeInplace(dataLength);
135 if (buf) {
136 memcpy(buf, exportData.get(), dataLength);
137 } else {
138 ALOGE("Failed to writeInplace ExportResult data.");
139 }
140 }
Bin Chen96d62712016-08-25 14:41:53 +1000141 return OK;
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800142}
143
144KeymasterArguments::KeymasterArguments() {
145}
146
147KeymasterArguments::~KeymasterArguments() {
148 keymaster_free_param_values(params.data(), params.size());
149}
150
151void KeymasterArguments::readFromParcel(const Parcel& in) {
152 ssize_t length = in.readInt32();
153 size_t ulength = (size_t) length;
154 if (length < 0) {
155 ulength = 0;
156 }
157 keymaster_free_param_values(params.data(), params.size());
158 params.clear();
159 for(size_t i = 0; i < ulength; i++) {
160 keymaster_key_param_t param;
161 if (!readKeymasterArgumentFromParcel(in, &param)) {
162 ALOGE("Error reading keymaster argument from parcel");
163 break;
164 }
165 params.push_back(param);
166 }
167}
168
169void KeymasterArguments::writeToParcel(Parcel* out) const {
170 out->writeInt32(params.size());
171 for (auto param : params) {
172 out->writeInt32(1);
173 writeKeymasterArgumentToParcel(param, out);
174 }
175}
176
177KeyCharacteristics::KeyCharacteristics() {
178 memset((void*) &characteristics, 0, sizeof(characteristics));
179}
180
181KeyCharacteristics::~KeyCharacteristics() {
182 keymaster_free_characteristics(&characteristics);
183}
184
185void KeyCharacteristics::readFromParcel(const Parcel& in) {
186 size_t length = 0;
187 keymaster_key_param_t* params = readParamList(in, &length);
188 characteristics.sw_enforced.params = params;
189 characteristics.sw_enforced.length = length;
190
191 params = readParamList(in, &length);
192 characteristics.hw_enforced.params = params;
193 characteristics.hw_enforced.length = length;
194}
195
196void KeyCharacteristics::writeToParcel(Parcel* out) const {
197 if (characteristics.sw_enforced.params) {
198 out->writeInt32(characteristics.sw_enforced.length);
199 for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
200 out->writeInt32(1);
201 writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
202 }
203 } else {
204 out->writeInt32(0);
205 }
206 if (characteristics.hw_enforced.params) {
207 out->writeInt32(characteristics.hw_enforced.length);
208 for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
209 out->writeInt32(1);
210 writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
211 }
212 } else {
213 out->writeInt32(0);
214 }
215}
216
Shawn Willden50eb1b22016-01-21 12:41:23 -0700217KeymasterCertificateChain::KeymasterCertificateChain() {
218 memset(&chain, 0, sizeof(chain));
219}
220
221KeymasterCertificateChain::~KeymasterCertificateChain() {
222 keymaster_free_cert_chain(&chain);
223}
224
225static bool readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
226 if (in.readInt32() != 1) {
227 return false;
228 }
229
Shawn Willden50eb1b22016-01-21 12:41:23 -0700230 ssize_t length = in.readInt32();
231 if (length <= 0) {
Shawn Willden50eb1b22016-01-21 12:41:23 -0700232 return false;
233 }
234
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700235 blob->data = reinterpret_cast<const uint8_t*>(malloc(length));
236 if (!blob->data)
237 return false;
238
239 const void* buf = in.readInplace(length);
240 if (!buf)
241 return false;
242
243 blob->data_length = static_cast<size_t>(length);
244 memcpy(const_cast<uint8_t*>(blob->data), buf, length);
245
Shawn Willden50eb1b22016-01-21 12:41:23 -0700246 return true;
247}
248
249void KeymasterCertificateChain::readFromParcel(const Parcel& in) {
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700250 keymaster_free_cert_chain(&chain);
251
Shawn Willden50eb1b22016-01-21 12:41:23 -0700252 ssize_t count = in.readInt32();
253 size_t ucount = count;
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700254 if (count <= 0) {
255 return;
Shawn Willden50eb1b22016-01-21 12:41:23 -0700256 }
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700257
258 chain.entries = reinterpret_cast<keymaster_blob_t*>(malloc(sizeof(keymaster_blob_t) * ucount));
259 if (!chain.entries) {
260 ALOGE("Error allocating memory for certificate chain");
261 return;
262 }
263
Shawn Willden50eb1b22016-01-21 12:41:23 -0700264 memset(chain.entries, 0, sizeof(keymaster_blob_t) * ucount);
265 for (size_t i = 0; i < ucount; ++i) {
266 if (!readKeymasterBlob(in, &chain.entries[i])) {
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700267 ALOGE("Error reading certificate from parcel");
Shawn Willden50eb1b22016-01-21 12:41:23 -0700268 keymaster_free_cert_chain(&chain);
269 return;
270 }
271 }
272}
273
274void KeymasterCertificateChain::writeToParcel(Parcel* out) const {
275 out->writeInt32(chain.entry_count);
276 for (size_t i = 0; i < chain.entry_count; ++i) {
277 if (chain.entries[i].data) {
278 out->writeInt32(1); // Tell Java side that object is not NULL
279 out->writeInt32(chain.entries[i].data_length);
280 void* buf = out->writeInplace(chain.entries[i].data_length);
281 if (buf) {
282 memcpy(buf, chain.entries[i].data, chain.entries[i].data_length);
283 } else {
284 ALOGE("Failed to writeInplace keymaster cert chain entry");
285 }
286 } else {
287 out->writeInt32(0); // Tell Java side this object is NULL.
288 ALOGE("Found NULL certificate chain entry");
289 }
290 }
291}
292
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800293void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
294 switch (keymaster_tag_get_type(param.tag)) {
295 case KM_ENUM:
296 case KM_ENUM_REP: {
297 out->writeInt32(param.tag);
298 out->writeInt32(param.enumerated);
299 break;
300 }
Shawn Willden0ebf13d2015-06-24 16:29:45 -0700301 case KM_UINT:
302 case KM_UINT_REP: {
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800303 out->writeInt32(param.tag);
304 out->writeInt32(param.integer);
305 break;
306 }
Shawn Willden0ebf13d2015-06-24 16:29:45 -0700307 case KM_ULONG:
308 case KM_ULONG_REP: {
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800309 out->writeInt32(param.tag);
310 out->writeInt64(param.long_integer);
311 break;
312 }
313 case KM_DATE: {
314 out->writeInt32(param.tag);
315 out->writeInt64(param.date_time);
316 break;
317 }
318 case KM_BOOL: {
319 out->writeInt32(param.tag);
320 break;
321 }
322 case KM_BIGNUM:
323 case KM_BYTES: {
324 out->writeInt32(param.tag);
325 out->writeInt32(param.blob.data_length);
326 void* buf = out->writeInplace(param.blob.data_length);
327 if (buf) {
328 memcpy(buf, param.blob.data, param.blob.data_length);
329 } else {
330 ALOGE("Failed to writeInplace keymaster blob param");
331 }
332 break;
333 }
334 default: {
335 ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
336 }
337 }
338}
339
340
341bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
342 if (in.readInt32() == 0) {
343 return false;
344 }
345 keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
346 switch (keymaster_tag_get_type(tag)) {
347 case KM_ENUM:
348 case KM_ENUM_REP: {
349 uint32_t value = in.readInt32();
350 *out = keymaster_param_enum(tag, value);
351 break;
352 }
Shawn Willden0ebf13d2015-06-24 16:29:45 -0700353 case KM_UINT:
354 case KM_UINT_REP: {
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800355 uint32_t value = in.readInt32();
356 *out = keymaster_param_int(tag, value);
357 break;
358 }
Shawn Willden0ebf13d2015-06-24 16:29:45 -0700359 case KM_ULONG:
360 case KM_ULONG_REP: {
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800361 uint64_t value = in.readInt64();
362 *out = keymaster_param_long(tag, value);
363 break;
364 }
365 case KM_DATE: {
366 uint64_t value = in.readInt64();
367 *out = keymaster_param_date(tag, value);
368 break;
369 }
370 case KM_BOOL: {
371 *out = keymaster_param_bool(tag);
372 break;
373 }
374 case KM_BIGNUM:
375 case KM_BYTES: {
376 ssize_t length = in.readInt32();
377 uint8_t* data = NULL;
378 size_t ulength = 0;
379 if (length >= 0) {
380 ulength = (size_t) length;
381 // use malloc here so we can use keymaster_free_param_values
382 // consistently.
383 data = reinterpret_cast<uint8_t*>(malloc(ulength));
384 const void* buf = in.readInplace(ulength);
385 if (!buf || !data) {
386 ALOGE("Failed to allocate buffer for keymaster blob param");
Shawn Willdeneb1adaf2016-02-02 17:32:31 -0700387 free(data);
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800388 return false;
389 }
390 memcpy(data, buf, ulength);
391 }
392 *out = keymaster_param_blob(tag, data, ulength);
393 break;
394 }
395 default: {
396 ALOGE("Unsupported keymaster_tag_t %d", tag);
397 return false;
398 }
399 }
400 return true;
401}
402
Chad Brubaker6432df72015-03-20 16:23:04 -0700403/**
404 * Read a byte array from in. The data at *data is still owned by the parcel
405 */
406static void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) {
407 ssize_t slength = in.readInt32();
408 if (slength > 0) {
409 *data = reinterpret_cast<const uint8_t*>(in.readInplace(slength));
410 if (*data) {
411 *length = static_cast<size_t>(slength);
412 } else {
413 *length = 0;
414 }
415 } else {
416 *data = NULL;
417 *length = 0;
418 }
419}
420
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800421// Read a keymaster_key_param_t* from a Parcel for use in a
422// keymaster_key_characteristics_t. This will be free'd by calling
423// keymaster_free_key_characteristics.
424static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
425 ssize_t slength = in.readInt32();
426 *length = 0;
427 if (slength < 0) {
428 return NULL;
429 }
430 *length = (size_t) slength;
431 if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
432 return NULL;
433 }
434 keymaster_key_param_t* list =
435 reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
436 sizeof(keymaster_key_param_t)));
437 if (!list) {
438 ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
439 goto err;
440 }
441 for (size_t i = 0; i < *length ; i++) {
442 if (!readKeymasterArgumentFromParcel(in, &list[i])) {
443 ALOGE("Failed to read keymaster argument");
444 keymaster_free_param_values(list, i);
445 goto err;
446 }
447 }
448 return list;
449err:
450 free(list);
451 return NULL;
452}
453
Chad Brubakerd6634422015-03-21 22:36:07 -0700454static std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
Shawn Willden50eb1b22016-01-21 12:41:23 -0700455 std::unique_ptr<keymaster_blob_t> blob (new keymaster_blob_t);
456 if (!readKeymasterBlob(in, blob.get())) {
457 blob.reset();
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800458 }
Chad Brubakerd6634422015-03-21 22:36:07 -0700459 return blob;
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800460}
461
Kenny Root07438c82012-11-02 15:41:02 -0700462class BpKeystoreService: public BpInterface<IKeystoreService>
463{
464public:
Chih-Hung Hsiehd3bccc82016-04-25 12:11:44 -0700465 explicit BpKeystoreService(const sp<IBinder>& impl)
Kenny Root07438c82012-11-02 15:41:02 -0700466 : BpInterface<IKeystoreService>(impl)
467 {
468 }
469
470 // test ping
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700471 virtual int32_t getState(int32_t userId)
Kenny Root07438c82012-11-02 15:41:02 -0700472 {
473 Parcel data, reply;
474 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700475 data.writeInt32(userId);
476 status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply);
Kenny Root07438c82012-11-02 15:41:02 -0700477 if (status != NO_ERROR) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700478 ALOGD("getState() could not contact remote: %d\n", status);
Kenny Root07438c82012-11-02 15:41:02 -0700479 return -1;
480 }
481 int32_t err = reply.readExceptionCode();
482 int32_t ret = reply.readInt32();
483 if (err < 0) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700484 ALOGD("getState() caught exception %d\n", err);
Kenny Root07438c82012-11-02 15:41:02 -0700485 return -1;
486 }
487 return ret;
488 }
489
490 virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
491 {
492 Parcel data, reply;
493 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
494 data.writeString16(name);
495 status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
496 if (status != NO_ERROR) {
497 ALOGD("get() could not contact remote: %d\n", status);
498 return -1;
499 }
500 int32_t err = reply.readExceptionCode();
501 ssize_t len = reply.readInt32();
502 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
503 size_t ulen = (size_t) len;
504 const void* buf = reply.readInplace(ulen);
505 *item = (uint8_t*) malloc(ulen);
506 if (*item != NULL) {
507 memcpy(*item, buf, ulen);
508 *itemLength = ulen;
509 } else {
510 ALOGE("out of memory allocating output array in get");
511 *itemLength = 0;
512 }
513 } else {
514 *itemLength = 0;
515 }
516 if (err < 0) {
517 ALOGD("get() caught exception %d\n", err);
518 return -1;
519 }
520 return 0;
521 }
522
Kenny Root0c540aa2013-04-03 09:22:15 -0700523 virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
524 int32_t flags)
Kenny Root07438c82012-11-02 15:41:02 -0700525 {
526 Parcel data, reply;
527 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
528 data.writeString16(name);
529 data.writeInt32(itemLength);
530 void* buf = data.writeInplace(itemLength);
531 memcpy(buf, item, itemLength);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800532 data.writeInt32(uid);
Kenny Root0c540aa2013-04-03 09:22:15 -0700533 data.writeInt32(flags);
Kenny Root07438c82012-11-02 15:41:02 -0700534 status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
535 if (status != NO_ERROR) {
536 ALOGD("import() could not contact remote: %d\n", status);
537 return -1;
538 }
539 int32_t err = reply.readExceptionCode();
540 int32_t ret = reply.readInt32();
541 if (err < 0) {
542 ALOGD("import() caught exception %d\n", err);
543 return -1;
544 }
545 return ret;
546 }
547
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800548 virtual int32_t del(const String16& name, int uid)
Kenny Root07438c82012-11-02 15:41:02 -0700549 {
550 Parcel data, reply;
551 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
552 data.writeString16(name);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800553 data.writeInt32(uid);
Kenny Root07438c82012-11-02 15:41:02 -0700554 status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
555 if (status != NO_ERROR) {
556 ALOGD("del() could not contact remote: %d\n", status);
557 return -1;
558 }
559 int32_t err = reply.readExceptionCode();
560 int32_t ret = reply.readInt32();
561 if (err < 0) {
562 ALOGD("del() caught exception %d\n", err);
563 return -1;
564 }
565 return ret;
566 }
567
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800568 virtual int32_t exist(const String16& name, int uid)
Kenny Root07438c82012-11-02 15:41:02 -0700569 {
570 Parcel data, reply;
571 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
572 data.writeString16(name);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800573 data.writeInt32(uid);
Kenny Root07438c82012-11-02 15:41:02 -0700574 status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
575 if (status != NO_ERROR) {
576 ALOGD("exist() could not contact remote: %d\n", status);
577 return -1;
578 }
579 int32_t err = reply.readExceptionCode();
580 int32_t ret = reply.readInt32();
581 if (err < 0) {
582 ALOGD("exist() caught exception %d\n", err);
583 return -1;
584 }
585 return ret;
586 }
587
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700588 virtual int32_t list(const String16& prefix, int uid, Vector<String16>* matches)
Kenny Root07438c82012-11-02 15:41:02 -0700589 {
590 Parcel data, reply;
591 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700592 data.writeString16(prefix);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800593 data.writeInt32(uid);
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700594 status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply);
Kenny Root07438c82012-11-02 15:41:02 -0700595 if (status != NO_ERROR) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700596 ALOGD("list() could not contact remote: %d\n", status);
Kenny Root07438c82012-11-02 15:41:02 -0700597 return -1;
598 }
599 int32_t err = reply.readExceptionCode();
600 int32_t numMatches = reply.readInt32();
601 for (int32_t i = 0; i < numMatches; i++) {
602 matches->push(reply.readString16());
603 }
604 int32_t ret = reply.readInt32();
605 if (err < 0) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700606 ALOGD("list() caught exception %d\n", err);
Kenny Root07438c82012-11-02 15:41:02 -0700607 return -1;
608 }
609 return ret;
610 }
611
612 virtual int32_t reset()
613 {
614 Parcel data, reply;
615 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
616 status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
617 if (status != NO_ERROR) {
618 ALOGD("reset() could not contact remote: %d\n", status);
619 return -1;
620 }
621 int32_t err = reply.readExceptionCode();
622 int32_t ret = reply.readInt32();
623 if (err < 0) {
624 ALOGD("reset() caught exception %d\n", err);
625 return -1;
626 }
627 return ret;
628 }
629
Chad Brubaker96d6d782015-05-07 10:19:40 -0700630 virtual int32_t onUserPasswordChanged(int32_t userId, const String16& password)
Kenny Root07438c82012-11-02 15:41:02 -0700631 {
632 Parcel data, reply;
633 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubaker96d6d782015-05-07 10:19:40 -0700634 data.writeInt32(userId);
Kenny Root07438c82012-11-02 15:41:02 -0700635 data.writeString16(password);
Chad Brubaker96d6d782015-05-07 10:19:40 -0700636 status_t status = remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data,
637 &reply);
Kenny Root07438c82012-11-02 15:41:02 -0700638 if (status != NO_ERROR) {
Chad Brubaker96d6d782015-05-07 10:19:40 -0700639 ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status);
Kenny Root07438c82012-11-02 15:41:02 -0700640 return -1;
641 }
642 int32_t err = reply.readExceptionCode();
643 int32_t ret = reply.readInt32();
644 if (err < 0) {
Chad Brubaker96d6d782015-05-07 10:19:40 -0700645 ALOGD("onUserPasswordChanged() caught exception %d\n", err);
Kenny Root07438c82012-11-02 15:41:02 -0700646 return -1;
647 }
648 return ret;
649 }
650
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700651 virtual int32_t lock(int32_t userId)
Kenny Root07438c82012-11-02 15:41:02 -0700652 {
653 Parcel data, reply;
654 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700655 data.writeInt32(userId);
Kenny Root07438c82012-11-02 15:41:02 -0700656 status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
657 if (status != NO_ERROR) {
658 ALOGD("lock() could not contact remote: %d\n", status);
659 return -1;
660 }
661 int32_t err = reply.readExceptionCode();
662 int32_t ret = reply.readInt32();
663 if (err < 0) {
664 ALOGD("lock() caught exception %d\n", err);
665 return -1;
666 }
667 return ret;
668 }
669
Chad Brubaker96d6d782015-05-07 10:19:40 -0700670 virtual int32_t unlock(int32_t userId, const String16& password)
Kenny Root07438c82012-11-02 15:41:02 -0700671 {
672 Parcel data, reply;
673 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubaker96d6d782015-05-07 10:19:40 -0700674 data.writeInt32(userId);
Kenny Root07438c82012-11-02 15:41:02 -0700675 data.writeString16(password);
676 status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
677 if (status != NO_ERROR) {
678 ALOGD("unlock() could not contact remote: %d\n", status);
679 return -1;
680 }
681 int32_t err = reply.readExceptionCode();
682 int32_t ret = reply.readInt32();
683 if (err < 0) {
684 ALOGD("unlock() caught exception %d\n", err);
685 return -1;
686 }
687 return ret;
688 }
689
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700690 virtual bool isEmpty(int32_t userId)
Kenny Root07438c82012-11-02 15:41:02 -0700691 {
692 Parcel data, reply;
693 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700694 data.writeInt32(userId);
695 status_t status = remote()->transact(BnKeystoreService::IS_EMPTY, data, &reply);
Kenny Root07438c82012-11-02 15:41:02 -0700696 if (status != NO_ERROR) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700697 ALOGD("isEmpty() could not contact remote: %d\n", status);
698 return false;
Kenny Root07438c82012-11-02 15:41:02 -0700699 }
700 int32_t err = reply.readExceptionCode();
701 int32_t ret = reply.readInt32();
702 if (err < 0) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700703 ALOGD("isEmpty() caught exception %d\n", err);
704 return false;
Kenny Root07438c82012-11-02 15:41:02 -0700705 }
Chad Brubakere6c3bfa2015-05-12 15:18:26 -0700706 return ret != 0;
Kenny Root07438c82012-11-02 15:41:02 -0700707 }
708
Kenny Root96427ba2013-08-16 14:02:41 -0700709 virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
710 int32_t flags, Vector<sp<KeystoreArg> >* args)
Kenny Root07438c82012-11-02 15:41:02 -0700711 {
712 Parcel data, reply;
713 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
714 data.writeString16(name);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800715 data.writeInt32(uid);
Kenny Root96427ba2013-08-16 14:02:41 -0700716 data.writeInt32(keyType);
717 data.writeInt32(keySize);
Kenny Root0c540aa2013-04-03 09:22:15 -0700718 data.writeInt32(flags);
Chad Brubaker468fc692015-01-13 17:33:14 -0800719 data.writeInt32(1);
Kenny Root96427ba2013-08-16 14:02:41 -0700720 data.writeInt32(args->size());
721 for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
722 sp<KeystoreArg> item = *it;
723 size_t keyLength = item->size();
724 data.writeInt32(keyLength);
725 void* buf = data.writeInplace(keyLength);
726 memcpy(buf, item->data(), keyLength);
727 }
Kenny Root07438c82012-11-02 15:41:02 -0700728 status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
729 if (status != NO_ERROR) {
730 ALOGD("generate() could not contact remote: %d\n", status);
731 return -1;
732 }
733 int32_t err = reply.readExceptionCode();
734 int32_t ret = reply.readInt32();
735 if (err < 0) {
736 ALOGD("generate() caught exception %d\n", err);
737 return -1;
738 }
739 return ret;
740 }
741
Kenny Root0c540aa2013-04-03 09:22:15 -0700742 virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
743 int flags)
Kenny Root07438c82012-11-02 15:41:02 -0700744 {
745 Parcel data, reply;
746 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
747 data.writeString16(name);
748 data.writeInt32(keyLength);
749 void* buf = data.writeInplace(keyLength);
750 memcpy(buf, key, keyLength);
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800751 data.writeInt32(uid);
Kenny Root0c540aa2013-04-03 09:22:15 -0700752 data.writeInt32(flags);
Kenny Root07438c82012-11-02 15:41:02 -0700753 status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
754 if (status != NO_ERROR) {
755 ALOGD("import() could not contact remote: %d\n", status);
756 return -1;
757 }
758 int32_t err = reply.readExceptionCode();
759 int32_t ret = reply.readInt32();
760 if (err < 0) {
761 ALOGD("import() caught exception %d\n", err);
762 return -1;
763 }
764 return ret;
765 }
766
767 virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
768 size_t* outLength)
769 {
770 Parcel data, reply;
771 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
772 data.writeString16(name);
773 data.writeInt32(inLength);
774 void* buf = data.writeInplace(inLength);
775 memcpy(buf, in, inLength);
776 status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
777 if (status != NO_ERROR) {
778 ALOGD("import() could not contact remote: %d\n", status);
779 return -1;
780 }
781 int32_t err = reply.readExceptionCode();
782 ssize_t len = reply.readInt32();
783 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
784 size_t ulen = (size_t) len;
785 const void* outBuf = reply.readInplace(ulen);
786 *out = (uint8_t*) malloc(ulen);
787 if (*out != NULL) {
788 memcpy((void*) *out, outBuf, ulen);
789 *outLength = ulen;
790 } else {
791 ALOGE("out of memory allocating output array in sign");
792 *outLength = 0;
793 }
794 } else {
795 *outLength = 0;
796 }
797 if (err < 0) {
798 ALOGD("import() caught exception %d\n", err);
799 return -1;
800 }
801 return 0;
802 }
803
804 virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
805 const uint8_t* signature, size_t signatureLength)
806 {
807 Parcel data, reply;
808 void* buf;
809
810 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
811 data.writeString16(name);
812 data.writeInt32(inLength);
813 buf = data.writeInplace(inLength);
814 memcpy(buf, in, inLength);
815 data.writeInt32(signatureLength);
816 buf = data.writeInplace(signatureLength);
817 memcpy(buf, signature, signatureLength);
818 status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
819 if (status != NO_ERROR) {
820 ALOGD("verify() could not contact remote: %d\n", status);
821 return -1;
822 }
823 int32_t err = reply.readExceptionCode();
824 int32_t ret = reply.readInt32();
825 if (err < 0) {
826 ALOGD("verify() caught exception %d\n", err);
827 return -1;
828 }
829 return ret;
830 }
831
832 virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
833 {
834 Parcel data, reply;
835 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
836 data.writeString16(name);
837 status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
838 if (status != NO_ERROR) {
839 ALOGD("get_pubkey() could not contact remote: %d\n", status);
840 return -1;
841 }
842 int32_t err = reply.readExceptionCode();
843 ssize_t len = reply.readInt32();
844 if (len >= 0 && (size_t) len <= reply.dataAvail()) {
845 size_t ulen = (size_t) len;
846 const void* buf = reply.readInplace(ulen);
847 *pubkey = (uint8_t*) malloc(ulen);
848 if (*pubkey != NULL) {
849 memcpy(*pubkey, buf, ulen);
850 *pubkeyLength = ulen;
851 } else {
852 ALOGE("out of memory allocating output array in get_pubkey");
853 *pubkeyLength = 0;
854 }
855 } else {
856 *pubkeyLength = 0;
857 }
858 if (err < 0) {
859 ALOGD("get_pubkey() caught exception %d\n", err);
860 return -1;
861 }
862 return 0;
863 }
864
Kenny Root07438c82012-11-02 15:41:02 -0700865 virtual int32_t grant(const String16& name, int32_t granteeUid)
866 {
867 Parcel data, reply;
868 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
869 data.writeString16(name);
870 data.writeInt32(granteeUid);
871 status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
872 if (status != NO_ERROR) {
873 ALOGD("grant() could not contact remote: %d\n", status);
874 return -1;
875 }
876 int32_t err = reply.readExceptionCode();
877 int32_t ret = reply.readInt32();
878 if (err < 0) {
879 ALOGD("grant() caught exception %d\n", err);
880 return -1;
881 }
882 return ret;
883 }
884
885 virtual int32_t ungrant(const String16& name, int32_t granteeUid)
886 {
887 Parcel data, reply;
888 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
889 data.writeString16(name);
890 data.writeInt32(granteeUid);
891 status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
892 if (status != NO_ERROR) {
893 ALOGD("ungrant() 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("ungrant() caught exception %d\n", err);
900 return -1;
901 }
902 return ret;
903 }
904
905 int64_t getmtime(const String16& name)
906 {
907 Parcel data, reply;
908 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
909 data.writeString16(name);
910 status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
911 if (status != NO_ERROR) {
912 ALOGD("getmtime() could not contact remote: %d\n", status);
913 return -1;
914 }
915 int32_t err = reply.readExceptionCode();
916 int64_t ret = reply.readInt64();
917 if (err < 0) {
918 ALOGD("getmtime() caught exception %d\n", err);
919 return -1;
920 }
921 return ret;
922 }
Kenny Root02254072013-03-20 11:48:19 -0700923
Kenny Rootd53bc922013-03-21 14:10:15 -0700924 virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
925 int32_t destUid)
Kenny Root02254072013-03-20 11:48:19 -0700926 {
927 Parcel data, reply;
928 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Kenny Rootd53bc922013-03-21 14:10:15 -0700929 data.writeString16(srcKey);
930 data.writeInt32(srcUid);
931 data.writeString16(destKey);
932 data.writeInt32(destUid);
933 status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
Kenny Root02254072013-03-20 11:48:19 -0700934 if (status != NO_ERROR) {
Kenny Rootd53bc922013-03-21 14:10:15 -0700935 ALOGD("duplicate() could not contact remote: %d\n", status);
Kenny Root02254072013-03-20 11:48:19 -0700936 return -1;
937 }
938 int32_t err = reply.readExceptionCode();
939 int32_t ret = reply.readInt32();
940 if (err < 0) {
Kenny Rootd53bc922013-03-21 14:10:15 -0700941 ALOGD("duplicate() caught exception %d\n", err);
Kenny Root02254072013-03-20 11:48:19 -0700942 return -1;
943 }
944 return ret;
945 }
Kenny Root43061232013-03-29 11:15:50 -0700946
Kenny Root1b0e3932013-09-05 13:06:32 -0700947 virtual int32_t is_hardware_backed(const String16& keyType)
Kenny Root43061232013-03-29 11:15:50 -0700948 {
949 Parcel data, reply;
950 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Kenny Root1b0e3932013-09-05 13:06:32 -0700951 data.writeString16(keyType);
Kenny Root43061232013-03-29 11:15:50 -0700952 status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
953 if (status != NO_ERROR) {
954 ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
955 return -1;
956 }
957 int32_t err = reply.readExceptionCode();
958 int32_t ret = reply.readInt32();
959 if (err < 0) {
960 ALOGD("is_hardware_backed() caught exception %d\n", err);
961 return -1;
962 }
963 return ret;
964 }
Kenny Root2ecc7a12013-04-01 16:29:11 -0700965
966 virtual int32_t clear_uid(int64_t uid)
967 {
968 Parcel data, reply;
969 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
970 data.writeInt64(uid);
971 status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
972 if (status != NO_ERROR) {
973 ALOGD("clear_uid() could not contact remote: %d\n", status);
974 return -1;
975 }
976 int32_t err = reply.readExceptionCode();
977 int32_t ret = reply.readInt32();
978 if (err < 0) {
979 ALOGD("clear_uid() caught exception %d\n", err);
980 return -1;
981 }
982 return ret;
983 }
Robin Lee4e865752014-08-19 17:37:55 +0100984
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800985 virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
986 {
987 Parcel data, reply;
988 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
Chad Brubaker9899d6b2015-02-03 13:03:00 -0800989 data.writeByteArray(bufLength, buf);
990 status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
991 if (status != NO_ERROR) {
992 ALOGD("addRngEntropy() could not contact remote: %d\n", status);
993 return -1;
994 }
995 int32_t err = reply.readExceptionCode();
996 int32_t ret = reply.readInt32();
997 if (err < 0) {
998 ALOGD("addRngEntropy() caught exception %d\n", err);
999 return -1;
1000 }
1001 return ret;
1002 };
1003
1004 virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
Chad Brubaker154d7692015-03-27 13:59:31 -07001005 const uint8_t* entropy, size_t entropyLength, int uid, int flags,
1006 KeyCharacteristics* outCharacteristics)
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001007 {
1008 Parcel data, reply;
1009 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1010 data.writeString16(name);
1011 data.writeInt32(1);
1012 params.writeToParcel(&data);
Chad Brubaker154d7692015-03-27 13:59:31 -07001013 data.writeByteArray(entropyLength, entropy);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001014 data.writeInt32(uid);
1015 data.writeInt32(flags);
1016 status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
1017 if (status != NO_ERROR) {
1018 ALOGD("generateKey() could not contact remote: %d\n", status);
1019 return KM_ERROR_UNKNOWN_ERROR;
1020 }
1021 int32_t err = reply.readExceptionCode();
1022 int32_t ret = reply.readInt32();
1023 if (err < 0) {
1024 ALOGD("generateKey() caught exception %d\n", err);
1025 return KM_ERROR_UNKNOWN_ERROR;
1026 }
1027 if (reply.readInt32() != 0 && outCharacteristics) {
1028 outCharacteristics->readFromParcel(reply);
1029 }
1030 return ret;
1031 }
1032 virtual int32_t getKeyCharacteristics(const String16& name,
Chad Brubakerd6634422015-03-21 22:36:07 -07001033 const keymaster_blob_t* clientId,
1034 const keymaster_blob_t* appData,
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001035 KeyCharacteristics* outCharacteristics)
1036 {
1037 Parcel data, reply;
1038 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1039 data.writeString16(name);
Chad Brubakerd6634422015-03-21 22:36:07 -07001040 if (clientId) {
1041 data.writeByteArray(clientId->data_length, clientId->data);
1042 } else {
1043 data.writeInt32(-1);
1044 }
1045 if (appData) {
1046 data.writeByteArray(appData->data_length, appData->data);
1047 } else {
1048 data.writeInt32(-1);
1049 }
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001050 status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
1051 data, &reply);
1052 if (status != NO_ERROR) {
1053 ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
1054 return KM_ERROR_UNKNOWN_ERROR;
1055 }
1056 int32_t err = reply.readExceptionCode();
1057 int32_t ret = reply.readInt32();
1058 if (err < 0) {
1059 ALOGD("getKeyCharacteristics() caught exception %d\n", err);
1060 return KM_ERROR_UNKNOWN_ERROR;
1061 }
1062 if (reply.readInt32() != 0 && outCharacteristics) {
1063 outCharacteristics->readFromParcel(reply);
1064 }
1065 return ret;
1066 }
1067 virtual int32_t importKey(const String16& name, const KeymasterArguments& params,
1068 keymaster_key_format_t format, const uint8_t *keyData,
1069 size_t keyLength, int uid, int flags,
1070 KeyCharacteristics* outCharacteristics)
1071 {
1072 Parcel data, reply;
1073 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1074 data.writeString16(name);
1075 data.writeInt32(1);
1076 params.writeToParcel(&data);
1077 data.writeInt32(format);
1078 data.writeByteArray(keyLength, keyData);
1079 data.writeInt32(uid);
1080 data.writeInt32(flags);
1081 status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
1082 if (status != NO_ERROR) {
1083 ALOGD("importKey() could not contact remote: %d\n", status);
1084 return KM_ERROR_UNKNOWN_ERROR;
1085 }
1086 int32_t err = reply.readExceptionCode();
1087 int32_t ret = reply.readInt32();
1088 if (err < 0) {
1089 ALOGD("importKey() caught exception %d\n", err);
1090 return KM_ERROR_UNKNOWN_ERROR;
1091 }
1092 if (reply.readInt32() != 0 && outCharacteristics) {
1093 outCharacteristics->readFromParcel(reply);
1094 }
1095 return ret;
1096 }
1097
1098 virtual void exportKey(const String16& name, keymaster_key_format_t format,
Chad Brubakerd6634422015-03-21 22:36:07 -07001099 const keymaster_blob_t* clientId,
1100 const keymaster_blob_t* appData, ExportResult* result)
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001101 {
1102 if (!result) {
1103 return;
1104 }
1105
1106 Parcel data, reply;
1107 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1108 data.writeString16(name);
1109 data.writeInt32(format);
Chad Brubakerd6634422015-03-21 22:36:07 -07001110 if (clientId) {
1111 data.writeByteArray(clientId->data_length, clientId->data);
1112 } else {
1113 data.writeInt32(-1);
1114 }
1115 if (appData) {
1116 data.writeByteArray(appData->data_length, appData->data);
1117 } else {
1118 data.writeInt32(-1);
1119 }
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001120 status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
1121 if (status != NO_ERROR) {
1122 ALOGD("exportKey() could not contact remote: %d\n", status);
1123 result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1124 return;
1125 }
1126 int32_t err = reply.readExceptionCode();
1127 if (err < 0) {
1128 ALOGD("exportKey() caught exception %d\n", err);
1129 result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1130 return;
1131 }
Bin Chen96d62712016-08-25 14:41:53 +10001132
1133 reply.readParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001134 }
1135
1136 virtual void begin(const sp<IBinder>& appToken, const String16& name,
1137 keymaster_purpose_t purpose, bool pruneable,
Chad Brubaker154d7692015-03-27 13:59:31 -07001138 const KeymasterArguments& params, const uint8_t* entropy,
Chad Brubaker57e106d2015-06-01 12:59:00 -07001139 size_t entropyLength, OperationResult* result)
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001140 {
Chad Brubaker57e106d2015-06-01 12:59:00 -07001141 if (!result) {
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001142 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);
Chad Brubaker154d7692015-03-27 13:59:31 -07001152 data.writeByteArray(entropyLength, entropy);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001153 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 }
Bin Chen9ec92702016-08-25 14:25:05 +10001165
1166 reply.readParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001167 }
1168
1169 virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
Chad Brubaker40a1a9b2015-02-20 14:08:13 -08001170 const uint8_t* opData, size_t dataLength, OperationResult* result)
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001171 {
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 }
Bin Chen9ec92702016-08-25 14:25:05 +10001193
1194 reply.readParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001195 }
1196
1197 virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
Chad Brubaker0d33e0b2015-05-29 12:30:19 -07001198 const uint8_t* signature, size_t signatureLength,
1199 const uint8_t* entropy, size_t entropyLength,
1200 OperationResult* result)
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001201 {
1202 if (!result) {
1203 return;
1204 }
1205 Parcel data, reply;
1206 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1207 data.writeStrongBinder(token);
1208 data.writeInt32(1);
1209 params.writeToParcel(&data);
1210 data.writeByteArray(signatureLength, signature);
Chad Brubaker0d33e0b2015-05-29 12:30:19 -07001211 data.writeByteArray(entropyLength, entropy);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001212 status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
1213 if (status != NO_ERROR) {
1214 ALOGD("finish() could not contact remote: %d\n", status);
1215 result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1216 return;
1217 }
1218 int32_t err = reply.readExceptionCode();
1219 if (err < 0) {
1220 ALOGD("finish() caught exception %d\n", err);
1221 result->resultCode = KM_ERROR_UNKNOWN_ERROR;
1222 return;
1223 }
Bin Chen9ec92702016-08-25 14:25:05 +10001224
1225 reply.readParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001226 }
1227
1228 virtual int32_t abort(const sp<IBinder>& token)
1229 {
1230 Parcel data, reply;
1231 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1232 data.writeStrongBinder(token);
Chad Brubaker2ed2baa2015-03-21 21:20:10 -07001233 status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001234 if (status != NO_ERROR) {
1235 ALOGD("abort() could not contact remote: %d\n", status);
1236 return KM_ERROR_UNKNOWN_ERROR;
1237 }
1238 int32_t err = reply.readExceptionCode();
1239 int32_t ret = reply.readInt32();
1240 if (err < 0) {
1241 ALOGD("abort() caught exception %d\n", err);
1242 return KM_ERROR_UNKNOWN_ERROR;
1243 }
1244 return ret;
1245 }
Chad Brubaker2ed2baa2015-03-21 21:20:10 -07001246
1247 virtual bool isOperationAuthorized(const sp<IBinder>& token)
1248 {
1249 Parcel data, reply;
1250 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1251 data.writeStrongBinder(token);
1252 status_t status = remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data,
1253 &reply);
1254 if (status != NO_ERROR) {
1255 ALOGD("isOperationAuthorized() could not contact remote: %d\n", status);
1256 return false;
1257 }
1258 int32_t err = reply.readExceptionCode();
1259 int32_t ret = reply.readInt32();
1260 if (err < 0) {
1261 ALOGD("isOperationAuthorized() caught exception %d\n", err);
1262 return false;
1263 }
1264 return ret == 1;
1265 }
1266
1267 virtual int32_t addAuthToken(const uint8_t* token, size_t length)
1268 {
1269 Parcel data, reply;
1270 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1271 data.writeByteArray(length, token);
1272 status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply);
1273 if (status != NO_ERROR) {
1274 ALOGD("addAuthToken() could not contact remote: %d\n", status);
1275 return -1;
1276 }
1277 int32_t err = reply.readExceptionCode();
1278 int32_t ret = reply.readInt32();
1279 if (err < 0) {
1280 ALOGD("addAuthToken() caught exception %d\n", err);
1281 return -1;
1282 }
1283 return ret;
1284 };
Chad Brubakerc0f031a2015-05-12 10:43:10 -07001285
1286 virtual int32_t onUserAdded(int32_t userId, int32_t parentId)
1287 {
1288 Parcel data, reply;
1289 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1290 data.writeInt32(userId);
1291 data.writeInt32(parentId);
1292 status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply);
1293 if (status != NO_ERROR) {
1294 ALOGD("onUserAdded() could not contact remote: %d\n", status);
1295 return -1;
1296 }
1297 int32_t err = reply.readExceptionCode();
1298 int32_t ret = reply.readInt32();
1299 if (err < 0) {
1300 ALOGD("onUserAdded() caught exception %d\n", err);
1301 return -1;
1302 }
1303 return ret;
1304 }
1305
1306 virtual int32_t onUserRemoved(int32_t userId)
1307 {
1308 Parcel data, reply;
1309 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1310 data.writeInt32(userId);
1311 status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply);
1312 if (status != NO_ERROR) {
1313 ALOGD("onUserRemoved() could not contact remote: %d\n", status);
1314 return -1;
1315 }
1316 int32_t err = reply.readExceptionCode();
1317 int32_t ret = reply.readInt32();
1318 if (err < 0) {
1319 ALOGD("onUserRemoved() caught exception %d\n", err);
1320 return -1;
1321 }
1322 return ret;
1323 }
1324
Shawn Willden50eb1b22016-01-21 12:41:23 -07001325 virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
1326 KeymasterCertificateChain* outChain) {
1327 if (!outChain)
1328 return KM_ERROR_OUTPUT_PARAMETER_NULL;
1329
1330 Parcel data, reply;
1331 data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
1332 data.writeString16(name);
1333 data.writeInt32(1); // params is not NULL.
1334 params.writeToParcel(&data);
1335
1336 status_t status = remote()->transact(BnKeystoreService::ATTEST_KEY, data, &reply);
1337 if (status != NO_ERROR) {
1338 ALOGD("attestkey() count not contact remote: %d\n", status);
1339 return KM_ERROR_UNKNOWN_ERROR;
1340 }
1341 int32_t err = reply.readExceptionCode();
1342 int32_t ret = reply.readInt32();
1343 if (err < 0) {
1344 ALOGD("attestKey() caught exception %d\n", err);
1345 return KM_ERROR_UNKNOWN_ERROR;
1346 }
1347 if (reply.readInt32() != 0) {
1348 outChain->readFromParcel(reply);
1349 }
1350 return ret;
1351 }
1352
Kenny Root07438c82012-11-02 15:41:02 -07001353};
1354
Chad Brubaker468fc692015-01-13 17:33:14 -08001355IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
Kenny Root07438c82012-11-02 15:41:02 -07001356
1357// ----------------------------------------------------------------------
1358
1359status_t BnKeystoreService::onTransact(
1360 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1361{
1362 switch(code) {
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001363 case GET_STATE: {
Kenny Root07438c82012-11-02 15:41:02 -07001364 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001365 int32_t userId = data.readInt32();
1366 int32_t ret = getState(userId);
Kenny Root07438c82012-11-02 15:41:02 -07001367 reply->writeNoException();
1368 reply->writeInt32(ret);
1369 return NO_ERROR;
1370 } break;
1371 case GET: {
1372 CHECK_INTERFACE(IKeystoreService, data, reply);
1373 String16 name = data.readString16();
1374 void* out = NULL;
1375 size_t outSize = 0;
1376 int32_t ret = get(name, (uint8_t**) &out, &outSize);
1377 reply->writeNoException();
1378 if (ret == 1) {
1379 reply->writeInt32(outSize);
1380 void* buf = reply->writeInplace(outSize);
1381 memcpy(buf, out, outSize);
1382 free(out);
1383 } else {
1384 reply->writeInt32(-1);
1385 }
1386 return NO_ERROR;
1387 } break;
1388 case INSERT: {
1389 CHECK_INTERFACE(IKeystoreService, data, reply);
1390 String16 name = data.readString16();
1391 ssize_t inSize = data.readInt32();
1392 const void* in;
1393 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1394 in = data.readInplace(inSize);
1395 } else {
1396 in = NULL;
1397 inSize = 0;
1398 }
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001399 int uid = data.readInt32();
Kenny Root0c540aa2013-04-03 09:22:15 -07001400 int32_t flags = data.readInt32();
1401 int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
Kenny Root07438c82012-11-02 15:41:02 -07001402 reply->writeNoException();
1403 reply->writeInt32(ret);
1404 return NO_ERROR;
1405 } break;
1406 case DEL: {
1407 CHECK_INTERFACE(IKeystoreService, data, reply);
1408 String16 name = data.readString16();
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001409 int uid = data.readInt32();
1410 int32_t ret = del(name, uid);
Kenny Root07438c82012-11-02 15:41:02 -07001411 reply->writeNoException();
1412 reply->writeInt32(ret);
1413 return NO_ERROR;
1414 } break;
1415 case EXIST: {
1416 CHECK_INTERFACE(IKeystoreService, data, reply);
1417 String16 name = data.readString16();
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001418 int uid = data.readInt32();
1419 int32_t ret = exist(name, uid);
Kenny Root07438c82012-11-02 15:41:02 -07001420 reply->writeNoException();
1421 reply->writeInt32(ret);
1422 return NO_ERROR;
1423 } break;
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001424 case LIST: {
Kenny Root07438c82012-11-02 15:41:02 -07001425 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001426 String16 prefix = data.readString16();
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001427 int uid = data.readInt32();
Kenny Root07438c82012-11-02 15:41:02 -07001428 Vector<String16> matches;
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001429 int32_t ret = list(prefix, uid, &matches);
Kenny Root07438c82012-11-02 15:41:02 -07001430 reply->writeNoException();
1431 reply->writeInt32(matches.size());
1432 Vector<String16>::const_iterator it = matches.begin();
1433 for (; it != matches.end(); ++it) {
1434 reply->writeString16(*it);
1435 }
1436 reply->writeInt32(ret);
1437 return NO_ERROR;
1438 } break;
1439 case RESET: {
1440 CHECK_INTERFACE(IKeystoreService, data, reply);
1441 int32_t ret = reset();
1442 reply->writeNoException();
1443 reply->writeInt32(ret);
1444 return NO_ERROR;
1445 } break;
Chad Brubaker96d6d782015-05-07 10:19:40 -07001446 case ON_USER_PASSWORD_CHANGED: {
Kenny Root07438c82012-11-02 15:41:02 -07001447 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubaker96d6d782015-05-07 10:19:40 -07001448 int32_t userId = data.readInt32();
Kenny Root07438c82012-11-02 15:41:02 -07001449 String16 pass = data.readString16();
Chad Brubaker96d6d782015-05-07 10:19:40 -07001450 int32_t ret = onUserPasswordChanged(userId, pass);
Kenny Root07438c82012-11-02 15:41:02 -07001451 reply->writeNoException();
1452 reply->writeInt32(ret);
1453 return NO_ERROR;
1454 } break;
1455 case LOCK: {
1456 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001457 int32_t userId = data.readInt32();
1458 int32_t ret = lock(userId);
Kenny Root07438c82012-11-02 15:41:02 -07001459 reply->writeNoException();
1460 reply->writeInt32(ret);
1461 return NO_ERROR;
1462 } break;
1463 case UNLOCK: {
1464 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubaker96d6d782015-05-07 10:19:40 -07001465 int32_t userId = data.readInt32();
Kenny Root07438c82012-11-02 15:41:02 -07001466 String16 pass = data.readString16();
Chad Brubaker96d6d782015-05-07 10:19:40 -07001467 int32_t ret = unlock(userId, pass);
Kenny Root07438c82012-11-02 15:41:02 -07001468 reply->writeNoException();
1469 reply->writeInt32(ret);
1470 return NO_ERROR;
1471 } break;
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001472 case IS_EMPTY: {
Kenny Root07438c82012-11-02 15:41:02 -07001473 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001474 int32_t userId = data.readInt32();
1475 bool ret = isEmpty(userId);
Kenny Root07438c82012-11-02 15:41:02 -07001476 reply->writeNoException();
Chad Brubakere6c3bfa2015-05-12 15:18:26 -07001477 reply->writeInt32(ret ? 1 : 0);
Kenny Root07438c82012-11-02 15:41:02 -07001478 return NO_ERROR;
1479 } break;
1480 case GENERATE: {
1481 CHECK_INTERFACE(IKeystoreService, data, reply);
1482 String16 name = data.readString16();
Kenny Root96427ba2013-08-16 14:02:41 -07001483 int32_t uid = data.readInt32();
1484 int32_t keyType = data.readInt32();
1485 int32_t keySize = data.readInt32();
Kenny Root0c540aa2013-04-03 09:22:15 -07001486 int32_t flags = data.readInt32();
Kenny Root96427ba2013-08-16 14:02:41 -07001487 Vector<sp<KeystoreArg> > args;
Chad Brubaker468fc692015-01-13 17:33:14 -08001488 int32_t argsPresent = data.readInt32();
1489 if (argsPresent == 1) {
1490 ssize_t numArgs = data.readInt32();
Chad Brubakered4f5662015-01-14 19:22:09 -08001491 if (numArgs > MAX_GENERATE_ARGS) {
1492 return BAD_VALUE;
1493 }
Chad Brubaker468fc692015-01-13 17:33:14 -08001494 if (numArgs > 0) {
1495 for (size_t i = 0; i < (size_t) numArgs; i++) {
1496 ssize_t inSize = data.readInt32();
1497 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1498 sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize),
1499 inSize);
1500 args.push_back(arg);
1501 } else {
1502 args.push_back(NULL);
1503 }
Kenny Root96427ba2013-08-16 14:02:41 -07001504 }
1505 }
1506 }
1507 int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
Kenny Root07438c82012-11-02 15:41:02 -07001508 reply->writeNoException();
1509 reply->writeInt32(ret);
1510 return NO_ERROR;
1511 } break;
1512 case IMPORT: {
1513 CHECK_INTERFACE(IKeystoreService, data, reply);
1514 String16 name = data.readString16();
1515 ssize_t inSize = data.readInt32();
1516 const void* in;
1517 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1518 in = data.readInplace(inSize);
1519 } else {
1520 in = NULL;
1521 inSize = 0;
1522 }
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001523 int uid = data.readInt32();
Kenny Root0c540aa2013-04-03 09:22:15 -07001524 int32_t flags = data.readInt32();
1525 int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
Kenny Root07438c82012-11-02 15:41:02 -07001526 reply->writeNoException();
1527 reply->writeInt32(ret);
1528 return NO_ERROR;
1529 } break;
1530 case SIGN: {
1531 CHECK_INTERFACE(IKeystoreService, data, reply);
1532 String16 name = data.readString16();
1533 ssize_t inSize = data.readInt32();
1534 const void* in;
1535 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1536 in = data.readInplace(inSize);
1537 } else {
1538 in = NULL;
1539 inSize = 0;
1540 }
1541 void* out = NULL;
1542 size_t outSize = 0;
1543 int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
1544 reply->writeNoException();
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001545 if (outSize > 0 && out != NULL) {
1546 reply->writeInt32(outSize);
1547 void* buf = reply->writeInplace(outSize);
1548 memcpy(buf, out, outSize);
Chad Brubaker3a7d9e62015-06-04 15:01:46 -07001549 delete[] reinterpret_cast<uint8_t*>(out);
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001550 } else {
Kenny Roote289c402013-02-14 11:31:53 -08001551 reply->writeInt32(-1);
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001552 }
Kenny Root07438c82012-11-02 15:41:02 -07001553 reply->writeInt32(ret);
1554 return NO_ERROR;
1555 } break;
1556 case VERIFY: {
1557 CHECK_INTERFACE(IKeystoreService, data, reply);
1558 String16 name = data.readString16();
1559 ssize_t inSize = data.readInt32();
1560 const void* in;
1561 if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
1562 in = data.readInplace(inSize);
1563 } else {
1564 in = NULL;
1565 inSize = 0;
1566 }
1567 ssize_t sigSize = data.readInt32();
1568 const void* sig;
1569 if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
1570 sig = data.readInplace(sigSize);
1571 } else {
1572 sig = NULL;
1573 sigSize = 0;
1574 }
1575 bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
1576 (size_t) sigSize);
1577 reply->writeNoException();
1578 reply->writeInt32(ret ? 1 : 0);
1579 return NO_ERROR;
1580 } break;
1581 case GET_PUBKEY: {
1582 CHECK_INTERFACE(IKeystoreService, data, reply);
1583 String16 name = data.readString16();
1584 void* out = NULL;
1585 size_t outSize = 0;
1586 int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
1587 reply->writeNoException();
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001588 if (outSize > 0 && out != NULL) {
1589 reply->writeInt32(outSize);
1590 void* buf = reply->writeInplace(outSize);
1591 memcpy(buf, out, outSize);
1592 free(out);
1593 } else {
Kenny Roote289c402013-02-14 11:31:53 -08001594 reply->writeInt32(-1);
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001595 }
Kenny Root07438c82012-11-02 15:41:02 -07001596 reply->writeInt32(ret);
1597 return NO_ERROR;
Kenny Rootb03c9fb2013-02-04 16:42:51 -08001598 } break;
Kenny Root07438c82012-11-02 15:41:02 -07001599 case GRANT: {
1600 CHECK_INTERFACE(IKeystoreService, data, reply);
1601 String16 name = data.readString16();
1602 int32_t granteeUid = data.readInt32();
1603 int32_t ret = grant(name, granteeUid);
1604 reply->writeNoException();
1605 reply->writeInt32(ret);
1606 return NO_ERROR;
1607 } break;
1608 case UNGRANT: {
1609 CHECK_INTERFACE(IKeystoreService, data, reply);
1610 String16 name = data.readString16();
1611 int32_t granteeUid = data.readInt32();
1612 int32_t ret = ungrant(name, granteeUid);
1613 reply->writeNoException();
1614 reply->writeInt32(ret);
1615 return NO_ERROR;
1616 } break;
1617 case GETMTIME: {
1618 CHECK_INTERFACE(IKeystoreService, data, reply);
1619 String16 name = data.readString16();
1620 int64_t ret = getmtime(name);
1621 reply->writeNoException();
1622 reply->writeInt64(ret);
1623 return NO_ERROR;
1624 } break;
Kenny Rootd53bc922013-03-21 14:10:15 -07001625 case DUPLICATE: {
Kenny Root02254072013-03-20 11:48:19 -07001626 CHECK_INTERFACE(IKeystoreService, data, reply);
Kenny Rootd53bc922013-03-21 14:10:15 -07001627 String16 srcKey = data.readString16();
1628 int32_t srcUid = data.readInt32();
1629 String16 destKey = data.readString16();
1630 int32_t destUid = data.readInt32();
1631 int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
Kenny Root02254072013-03-20 11:48:19 -07001632 reply->writeNoException();
1633 reply->writeInt32(ret);
1634 return NO_ERROR;
1635 } break;
Kenny Root43061232013-03-29 11:15:50 -07001636 case IS_HARDWARE_BACKED: {
1637 CHECK_INTERFACE(IKeystoreService, data, reply);
Kenny Root1b0e3932013-09-05 13:06:32 -07001638 String16 keyType = data.readString16();
1639 int32_t ret = is_hardware_backed(keyType);
Kenny Root43061232013-03-29 11:15:50 -07001640 reply->writeNoException();
1641 reply->writeInt32(ret);
1642 return NO_ERROR;
1643 }
Kenny Root2ecc7a12013-04-01 16:29:11 -07001644 case CLEAR_UID: {
1645 CHECK_INTERFACE(IKeystoreService, data, reply);
1646 int64_t uid = data.readInt64();
1647 int32_t ret = clear_uid(uid);
1648 reply->writeNoException();
1649 reply->writeInt32(ret);
1650 return NO_ERROR;
1651 }
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001652 case ADD_RNG_ENTROPY: {
1653 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubaker6432df72015-03-20 16:23:04 -07001654 const uint8_t* bytes = NULL;
1655 size_t size = 0;
1656 readByteArray(data, &bytes, &size);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001657 int32_t ret = addRngEntropy(bytes, size);
1658 reply->writeNoException();
1659 reply->writeInt32(ret);
1660 return NO_ERROR;
1661 }
1662 case GENERATE_KEY: {
1663 CHECK_INTERFACE(IKeystoreService, data, reply);
1664 String16 name = data.readString16();
1665 KeymasterArguments args;
1666 if (data.readInt32() != 0) {
1667 args.readFromParcel(data);
1668 }
Chad Brubaker154d7692015-03-27 13:59:31 -07001669 const uint8_t* entropy = NULL;
1670 size_t entropyLength = 0;
1671 readByteArray(data, &entropy, &entropyLength);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001672 int32_t uid = data.readInt32();
1673 int32_t flags = data.readInt32();
1674 KeyCharacteristics outCharacteristics;
Chad Brubaker154d7692015-03-27 13:59:31 -07001675 int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
1676 &outCharacteristics);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001677 reply->writeNoException();
1678 reply->writeInt32(ret);
1679 reply->writeInt32(1);
1680 outCharacteristics.writeToParcel(reply);
1681 return NO_ERROR;
1682 }
1683 case GET_KEY_CHARACTERISTICS: {
1684 CHECK_INTERFACE(IKeystoreService, data, reply);
1685 String16 name = data.readString16();
Chad Brubakerd6634422015-03-21 22:36:07 -07001686 std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1687 std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001688 KeyCharacteristics outCharacteristics;
Chad Brubakerd6634422015-03-21 22:36:07 -07001689 int ret = getKeyCharacteristics(name, clientId.get(), appData.get(),
1690 &outCharacteristics);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001691 reply->writeNoException();
1692 reply->writeInt32(ret);
1693 reply->writeInt32(1);
1694 outCharacteristics.writeToParcel(reply);
1695 return NO_ERROR;
1696 }
1697 case IMPORT_KEY: {
1698 CHECK_INTERFACE(IKeystoreService, data, reply);
1699 String16 name = data.readString16();
1700 KeymasterArguments args;
1701 if (data.readInt32() != 0) {
1702 args.readFromParcel(data);
1703 }
1704 keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
Chad Brubaker6432df72015-03-20 16:23:04 -07001705 const uint8_t* keyData = NULL;
1706 size_t keyLength = 0;
1707 readByteArray(data, &keyData, &keyLength);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001708 int32_t uid = data.readInt32();
1709 int32_t flags = data.readInt32();
1710 KeyCharacteristics outCharacteristics;
Chad Brubaker6432df72015-03-20 16:23:04 -07001711 int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001712 &outCharacteristics);
1713 reply->writeNoException();
1714 reply->writeInt32(ret);
1715 reply->writeInt32(1);
1716 outCharacteristics.writeToParcel(reply);
1717
1718 return NO_ERROR;
1719 }
1720 case EXPORT_KEY: {
1721 CHECK_INTERFACE(IKeystoreService, data, reply);
1722 String16 name = data.readString16();
1723 keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
Chad Brubakerd6634422015-03-21 22:36:07 -07001724 std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
1725 std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001726 ExportResult result;
Chad Brubakerd6634422015-03-21 22:36:07 -07001727 exportKey(name, format, clientId.get(), appData.get(), &result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001728 reply->writeNoException();
Bin Chen96d62712016-08-25 14:41:53 +10001729 reply->writeParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001730
1731 return NO_ERROR;
1732 }
1733 case BEGIN: {
1734 CHECK_INTERFACE(IKeystoreService, data, reply);
1735 sp<IBinder> token = data.readStrongBinder();
1736 String16 name = data.readString16();
1737 keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
1738 bool pruneable = data.readInt32() != 0;
1739 KeymasterArguments args;
1740 if (data.readInt32() != 0) {
1741 args.readFromParcel(data);
1742 }
Chad Brubaker154d7692015-03-27 13:59:31 -07001743 const uint8_t* entropy = NULL;
1744 size_t entropyLength = 0;
1745 readByteArray(data, &entropy, &entropyLength);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001746 OperationResult result;
Chad Brubaker57e106d2015-06-01 12:59:00 -07001747 begin(token, name, purpose, pruneable, args, entropy, entropyLength, &result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001748 reply->writeNoException();
Bin Chen9ec92702016-08-25 14:25:05 +10001749 reply->writeParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001750
1751 return NO_ERROR;
1752 }
1753 case UPDATE: {
1754 CHECK_INTERFACE(IKeystoreService, data, reply);
1755 sp<IBinder> token = data.readStrongBinder();
1756 KeymasterArguments args;
1757 if (data.readInt32() != 0) {
1758 args.readFromParcel(data);
1759 }
Chad Brubaker6432df72015-03-20 16:23:04 -07001760 const uint8_t* buf = NULL;
1761 size_t bufLength = 0;
1762 readByteArray(data, &buf, &bufLength);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001763 OperationResult result;
Chad Brubaker6432df72015-03-20 16:23:04 -07001764 update(token, args, buf, bufLength, &result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001765 reply->writeNoException();
Bin Chen9ec92702016-08-25 14:25:05 +10001766 reply->writeParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001767
1768 return NO_ERROR;
1769 }
1770 case FINISH: {
1771 CHECK_INTERFACE(IKeystoreService, data, reply);
1772 sp<IBinder> token = data.readStrongBinder();
1773 KeymasterArguments args;
1774 if (data.readInt32() != 0) {
1775 args.readFromParcel(data);
1776 }
Chad Brubaker0d33e0b2015-05-29 12:30:19 -07001777 const uint8_t* signature = NULL;
1778 size_t signatureLength = 0;
1779 readByteArray(data, &signature, &signatureLength);
1780 const uint8_t* entropy = NULL;
1781 size_t entropyLength = 0;
1782 readByteArray(data, &entropy, &entropyLength);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001783 OperationResult result;
Chad Brubaker0d33e0b2015-05-29 12:30:19 -07001784 finish(token, args, signature, signatureLength, entropy, entropyLength, &result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001785 reply->writeNoException();
Bin Chen9ec92702016-08-25 14:25:05 +10001786 reply->writeParcelable(result);
Chad Brubaker9899d6b2015-02-03 13:03:00 -08001787
1788 return NO_ERROR;
1789 }
1790 case ABORT: {
1791 CHECK_INTERFACE(IKeystoreService, data, reply);
1792 sp<IBinder> token = data.readStrongBinder();
1793 int32_t result = abort(token);
1794 reply->writeNoException();
1795 reply->writeInt32(result);
1796
1797 return NO_ERROR;
1798 }
Chad Brubaker2ed2baa2015-03-21 21:20:10 -07001799 case IS_OPERATION_AUTHORIZED: {
1800 CHECK_INTERFACE(IKeystoreService, data, reply);
1801 sp<IBinder> token = data.readStrongBinder();
1802 bool result = isOperationAuthorized(token);
1803 reply->writeNoException();
1804 reply->writeInt32(result ? 1 : 0);
1805
1806 return NO_ERROR;
1807 }
1808 case ADD_AUTH_TOKEN: {
1809 CHECK_INTERFACE(IKeystoreService, data, reply);
Chad Brubaker2ed2baa2015-03-21 21:20:10 -07001810 const uint8_t* token_bytes = NULL;
1811 size_t size = 0;
1812 readByteArray(data, &token_bytes, &size);
1813 int32_t result = addAuthToken(token_bytes, size);
1814 reply->writeNoException();
1815 reply->writeInt32(result);
1816
1817 return NO_ERROR;
1818 }
Chad Brubakerc0f031a2015-05-12 10:43:10 -07001819 case ON_USER_ADDED: {
1820 CHECK_INTERFACE(IKeystoreService, data, reply);
1821 int32_t userId = data.readInt32();
1822 int32_t parentId = data.readInt32();
1823 int32_t result = onUserAdded(userId, parentId);
1824 reply->writeNoException();
1825 reply->writeInt32(result);
1826
1827 return NO_ERROR;
1828 }
1829 case ON_USER_REMOVED: {
1830 CHECK_INTERFACE(IKeystoreService, data, reply);
1831 int32_t userId = data.readInt32();
1832 int32_t result = onUserRemoved(userId);
1833 reply->writeNoException();
1834 reply->writeInt32(result);
1835
1836 return NO_ERROR;
1837 }
Kenny Root07438c82012-11-02 15:41:02 -07001838 default:
1839 return BBinder::onTransact(code, data, reply, flags);
1840 }
1841}
1842
1843// ----------------------------------------------------------------------------
1844
1845}; // namespace android