blob: 0c388c751d6813a999aafa3cd2d5007b3fbd4ba7 [file] [log] [blame]
Ajay Dudanifb5cdde2012-09-20 14:57:01 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you
5 * may not use this file except in compliance with the License. You may
6 * obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 * implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
16
17#include <errno.h>
18#include <string.h>
19#include <stdint.h>
20
21#include <hardware/hardware.h>
22#include <hardware/keymaster.h>
23
24#include <openssl/evp.h>
25#include <openssl/bio.h>
26#include <openssl/rsa.h>
27#include <openssl/err.h>
28#include <openssl/x509.h>
29
30#include <utils/UniquePtr.h>
31#include <linux/ioctl.h>
32#include <linux/msm_ion.h>
33#include <sys/mman.h>
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <stddef.h>
38#include <unistd.h>
39#include <dirent.h>
40#include <fcntl.h>
41
42#include <sys/types.h>
43#include <sys/stat.h>
44#include <dlfcn.h>
45
46#include "QSEEComAPI.h"
47#include "keymaster_qcom.h"
48
49// For debugging
50//#define LOG_NDEBUG 0
51
52#define LOG_TAG "QCOMKeyMaster"
53#include <cutils/log.h>
54struct qcom_km_ion_info_t {
55 int32_t ion_fd;
56 int32_t ifd_data_fd;
57 struct ion_handle_data ion_alloc_handle;
58 unsigned char * ion_sbuffer;
59 uint32_t sbuf_len;
60};
61
62struct qcom_keymaster_handle {
63 struct QSEECom_handle *qseecom;
64 void *libhandle;
Ajay Dudani0cd599c2013-04-22 15:10:32 -070065 int (*QSEECom_start_app)(struct QSEECom_handle ** handle, char* path,
66 char* appname, uint32_t size);
Ajay Dudanifb5cdde2012-09-20 14:57:01 -070067 int (*QSEECom_shutdown_app)(struct QSEECom_handle **handle);
68 int (*QSEECom_send_cmd)(struct QSEECom_handle* handle, void *cbuf,
69 uint32_t clen, void *rbuf, uint32_t rlen);
70 int (*QSEECom_send_modified_cmd)(struct QSEECom_handle* handle, void *cbuf,
71 uint32_t clen, void *rbuf, uint32_t rlen,
72 struct QSEECom_ion_fd_info *ihandle);
73};
74typedef struct qcom_keymaster_handle qcom_keymaster_handle_t;
75
76struct EVP_PKEY_Delete {
77 void operator()(EVP_PKEY* p) const {
78 EVP_PKEY_free(p);
79 }
80};
81typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
82
83struct RSA_Delete {
84 void operator()(RSA* p) const {
85 RSA_free(p);
86 }
87};
88typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
89
90typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
91
92/**
93 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
94 * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
95 * without triggering a warning by not using the result of release().
96 */
97#define OWNERSHIP_TRANSFERRED(obj) \
98 typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
99
100static int qcom_km_get_keypair_public(const keymaster_device* dev,
101 const uint8_t* keyBlob, const size_t keyBlobLength,
102 uint8_t** x509_data, size_t* x509_data_length) {
103
104 struct qcom_km_key_blob * keyblob_ptr = (struct qcom_km_key_blob *)keyBlob;
105
106 if (x509_data == NULL || x509_data_length == NULL) {
107 ALOGE("Output public key buffer == NULL");
108 return -1;
109 }
110
111 if (keyBlob == NULL) {
112 ALOGE("Supplied key blob was NULL");
113 return -1;
114 }
115
116 // Should be large enough for keyblob data:
117 if (keyBlobLength < (sizeof(qcom_km_key_blob_t))) {
118 ALOGE("key blob appears to be truncated");
119 return -1;
120 }
121
122 if (keyblob_ptr->magic_num != KM_MAGIC_NUM) {
123 ALOGE("Cannot read key; it was not made by this keymaster");
124 return -1;
125 }
126
127 if (keyblob_ptr->public_exponent_size == 0 ) {
128 ALOGE("Key blob appears to have incorrect exponent length");
129 return -1;
130 }
131 if (keyblob_ptr->modulus_size == 0 ) {
132 ALOGE("Key blob appears to have incorrect modulus length");
133 return -1;
134 }
135
136 Unique_RSA rsa(RSA_new());
137 if (rsa.get() == NULL) {
138 ALOGE("Could not allocate RSA structure");
139 return -1;
140 }
141
142 rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(keyblob_ptr->modulus),
143 keyblob_ptr->modulus_size, NULL);
144 if (rsa->n == NULL) {
145 ALOGE("Failed to initialize modulus");
146 return -1;
147 }
148
149 rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(&keyblob_ptr->public_exponent),
150 keyblob_ptr->public_exponent_size, NULL);
151 if (rsa->e == NULL) {
152 ALOGE("Failed to initialize public exponent");
153 return -1;
154 }
155
156 Unique_EVP_PKEY pkey(EVP_PKEY_new());
157 if (pkey.get() == NULL) {
158 ALOGE("Could not allocate EVP_PKEY structure");
159 return -1;
160 }
161 if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
162 ALOGE("Failed to assign rsa parameters \n");
163 return -1;
164 }
165 OWNERSHIP_TRANSFERRED(rsa);
166
167 int len = i2d_PUBKEY(pkey.get(), NULL);
168 if (len <= 0) {
169 ALOGE("Len returned is < 0 len = %d", len);
170 return -1;
171 }
172
173 UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
174 if (key.get() == NULL) {
175 ALOGE("Could not allocate memory for public key data");
176 return -1;
177 }
178
179 unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
180 if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
181 ALOGE("Len 2 returned is < 0 len = %d", len);
182 return -1;
183 }
184 *x509_data_length = len;
185 *x509_data = key.release();
186
187 return 0;
188}
189
190static int32_t qcom_km_ION_memalloc(struct qcom_km_ion_info_t *handle,
191 uint32_t size)
192{
193 int32_t ret = 0;
194 int32_t iret = 0;
195 int32_t fd = 0;
196 unsigned char *v_addr;
197 struct ion_allocation_data ion_alloc_data;
198 int32_t ion_fd;
199 int32_t rc;
200 struct ion_fd_data ifd_data;
201 struct ion_handle_data handle_data;
202
203 /* open ION device for memory management
204 * O_DSYNC -> uncached memory
205 */
206 if(handle == NULL){
207 ALOGE("Error:: null handle received");
208 return -1;
209 }
210 ion_fd = open("/dev/ion", O_RDONLY | O_DSYNC);
211 if (ion_fd < 0) {
212 ALOGE("Error::Cannot open ION device");
213 return -1;
214 }
215 handle->ion_sbuffer = NULL;
216 handle->ifd_data_fd = 0;
217
218 /* Size of allocation */
219 ion_alloc_data.len = (size + 4095) & (~4095);
220
221 /* 4K aligned */
222 ion_alloc_data.align = 4096;
223
224 /* memory is allocated from EBI heap */
Ajay Dudani0cd599c2013-04-22 15:10:32 -0700225 ion_alloc_data.heap_mask= ION_HEAP(ION_QSECOM_HEAP_ID);
Ajay Dudanifb5cdde2012-09-20 14:57:01 -0700226
227 /* Set the memory to be uncached */
Ajay Dudani0cd599c2013-04-22 15:10:32 -0700228 ion_alloc_data.flags = 0;
Ajay Dudanifb5cdde2012-09-20 14:57:01 -0700229
230 /* IOCTL call to ION for memory request */
231 rc = ioctl(ion_fd, ION_IOC_ALLOC, &ion_alloc_data);
232 if (rc) {
233 ret = -1;
234 goto alloc_fail;
235 }
236
237 if (ion_alloc_data.handle != NULL) {
238 ifd_data.handle = ion_alloc_data.handle;
239 } else {
240 ret = -1;
241 goto alloc_fail;
242 }
243 /* Call MAP ioctl to retrieve the ifd_data.fd file descriptor */
244 rc = ioctl(ion_fd, ION_IOC_MAP, &ifd_data);
245 if (rc) {
246 ret = -1;
247 goto ioctl_fail;
248 }
249
250 /* Make the ion mmap call */
251 v_addr = (unsigned char *)mmap(NULL, ion_alloc_data.len,
252 PROT_READ | PROT_WRITE,
253 MAP_SHARED, ifd_data.fd, 0);
254 if (v_addr == MAP_FAILED) {
255 ALOGE("Error::ION MMAP failed");
256 ret = -1;
257 goto map_fail;
258 }
259 handle->ion_fd = ion_fd;
260 handle->ifd_data_fd = ifd_data.fd;
261 handle->ion_sbuffer = v_addr;
262 handle->ion_alloc_handle.handle = ion_alloc_data.handle;
263 handle->sbuf_len = size;
264 return ret;
265
266map_fail:
267 if (handle->ion_sbuffer != NULL) {
268 iret = munmap(handle->ion_sbuffer, ion_alloc_data.len);
269 if (iret)
270 ALOGE("Error::Failed to unmap memory for load image. ret = %d", ret);
271 }
272
273ioctl_fail:
274 handle_data.handle = ion_alloc_data.handle;
275 if (handle->ifd_data_fd)
276 close(handle->ifd_data_fd);
277 iret = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
278 if (iret) {
279 ALOGE("Error::ION FREE ioctl returned error = %d",iret);
280 }
281
282alloc_fail:
283 if (ion_fd > 0)
284 close(ion_fd);
285 return ret;
286}
287
288/** @brief: Deallocate ION memory
289 *
290 *
291 */
292static int32_t qcom_km_ion_dealloc(struct qcom_km_ion_info_t *handle)
293{
294 struct ion_handle_data handle_data;
295 int32_t ret = 0;
296
297 /* Deallocate the memory for the listener */
298 ret = munmap(handle->ion_sbuffer, (handle->sbuf_len + 4095) & (~4095));
299 if (ret) {
300 ALOGE("Error::Unmapping ION Buffer failed with ret = %d", ret);
301 }
302
303 handle_data.handle = handle->ion_alloc_handle.handle;
304 close(handle->ifd_data_fd);
305 ret = ioctl(handle->ion_fd, ION_IOC_FREE, &handle_data);
306 if (ret) {
307 ALOGE("Error::ION Memory FREE ioctl failed with ret = %d", ret);
308 }
309 close(handle->ion_fd);
310 return ret;
311}
312
313static int qcom_km_generate_keypair(const keymaster_device_t* dev,
314 const keymaster_keypair_t key_type, const void* key_params,
315 uint8_t** keyBlob, size_t* keyBlobLength) {
316
317 if (dev->context == NULL) {
318 ALOGE("qcom_km_generate_keypair: Context == NULL");
319 return -1;
320 }
321
322 if (key_type != TYPE_RSA) {
323 ALOGE("Unsupported key type %d", key_type);
324 return -1;
325 } else if (key_params == NULL) {
326 ALOGE("key_params == null");
327 return -1;
328 }
329 if (keyBlob == NULL || keyBlobLength == NULL) {
330 ALOGE("output key blob or length == NULL");
331 return -1;
332 }
333 keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;
334
335 keymaster_gen_keypair_cmd_t *send_cmd = NULL;
336 keymaster_gen_keypair_resp_t *resp = NULL;
337 struct QSEECom_handle *handle = NULL;
338 struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
339 int ret = 0;
340
341 handle = (struct QSEECom_handle *)(km_handle->qseecom);
342 send_cmd = (keymaster_gen_keypair_cmd_t *)handle->ion_sbuffer;
343 resp = (keymaster_gen_keypair_resp_t *)(handle->ion_sbuffer +
344 QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)));
345 send_cmd->cmd_id = KEYMASTER_GENERATE_KEYPAIR;
346 send_cmd->key_type = key_type;
347 send_cmd->rsa_params.modulus_size = rsa_params->modulus_size;
348 send_cmd->rsa_params.public_exponent = rsa_params->public_exponent;
349 resp->status = KEYMASTER_FAILURE;
350 resp->key_blob_len = sizeof(qcom_km_key_blob_t);
351
352 ret = (*km_handle->QSEECom_send_cmd)(handle, send_cmd,
353 QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)), resp,
354 QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_resp_t)));
355
356 if ( (ret < 0) || (resp->status < 0)) {
357 ALOGE("Generate key command failed resp->status = %d ret =%d", resp->status, ret);
358 return -1;
359 } else {
360 UniquePtr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
361 if (keydata.get() == NULL) {
362 ALOGE("could not allocate memory for key blob");
363 return -1;
364 }
365 unsigned char* p = keydata.get();
366 memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
367 *keyBlob = keydata.release();
368 *keyBlobLength = resp->key_blob_len;
369 }
370 return 0;
371}
372
373static int qcom_km_import_keypair(const keymaster_device_t* dev,
374 const uint8_t* key, const size_t key_length,
375 uint8_t** keyBlob, size_t* keyBlobLength)
376{
377 if (dev->context == NULL) {
378 ALOGE("qcom_km_import_keypair: Context == NULL");
379 return -1;
380 }
381
382 if (key == NULL) {
383 ALOGE("Input key == NULL");
384 return -1;
385 } else if (keyBlob == NULL || keyBlobLength == NULL) {
386 ALOGE("Output key blob or length == NULL");
387 return -1;
388 }
389
390 struct QSEECom_ion_fd_info ion_fd_info;
391 struct qcom_km_ion_info_t ihandle;
392 int ret = 0;
393
394 ihandle.ion_fd = 0;
395 ihandle.ion_alloc_handle.handle = NULL;
396 if (qcom_km_ION_memalloc(&ihandle, QSEECOM_ALIGN(key_length)) < 0) {
397 ALOGE("ION allocation failed");
398 return -1;
399 }
400 memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));
401
402 /* Populate the send data structure */
403 ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
404 ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t);
405
406
407 struct QSEECom_handle *handle = NULL;
408 keymaster_import_keypair_cmd_t *send_cmd = NULL;
409 keymaster_import_keypair_resp_t *resp = NULL;
410 struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
411
412 handle = (struct QSEECom_handle *)(km_handle->qseecom);
413 send_cmd = (keymaster_import_keypair_cmd_t *)handle->ion_sbuffer;
414 resp = (keymaster_import_keypair_resp_t *)(handle->ion_sbuffer +
415 QSEECOM_ALIGN(sizeof(keymaster_import_keypair_cmd_t)));
416 send_cmd->cmd_id = KEYMASTER_IMPORT_KEYPAIR;
417 send_cmd->pkcs8_key = (uint32_t)ihandle.ion_sbuffer;
418
419 memcpy((unsigned char *)ihandle.ion_sbuffer, key, key_length);
420
421 send_cmd->pkcs8_key_len = key_length;
422 resp->status = KEYMASTER_FAILURE;
423 resp->key_blob_len = sizeof(qcom_km_key_blob_t);
424
425 ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
426 QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
427 QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);
428
429 if ( (ret < 0) || (resp->status < 0)) {
430 ALOGE("Import key command failed resp->status = %d ret =%d", resp->status, ret);
431 qcom_km_ion_dealloc(&ihandle);
432 return -1;
433 } else {
434 UniquePtr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
435 if (keydata.get() == NULL) {
436 ALOGE("could not allocate memory for key blob");
437 return -1;
438 }
439 unsigned char* p = keydata.get();
440 memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
441 *keyBlob = keydata.release();
442 *keyBlobLength = resp->key_blob_len;
443
444 }
445 qcom_km_ion_dealloc(&ihandle);
446 return 0;
447}
448
449static int qcom_km_sign_data(const keymaster_device_t* dev,
450 const void* params,
451 const uint8_t* keyBlob, const size_t keyBlobLength,
452 const uint8_t* data, const size_t dataLength,
453 uint8_t** signedData, size_t* signedDataLength)
454{
455 if (dev->context == NULL) {
456 ALOGE("qcom_km_sign_data: Context == NULL");
457 return -1;
458 }
459 if (dataLength > KM_KEY_SIZE_MAX) {
460 ALOGE("Input data to be signed is too long %d bytes", dataLength);
461 return -1;
462 }
463 if (data == NULL) {
464 ALOGE("input data to sign == NULL");
465 return -1;
466 } else if (signedData == NULL || signedDataLength == NULL) {
467 ALOGE("Output signature buffer == NULL");
468 return -1;
469 }
470 keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
471 if (sign_params->digest_type != DIGEST_NONE) {
472 ALOGE("Cannot handle digest type %d", sign_params->digest_type);
473 return -1;
474 } else if (sign_params->padding_type != PADDING_NONE) {
475 ALOGE("Cannot handle padding type %d", sign_params->padding_type);
476 return -1;
477 }
478
479 struct QSEECom_handle *handle = NULL;
480 keymaster_sign_data_cmd_t *send_cmd = NULL;
481 keymaster_sign_data_resp_t *resp = NULL;
482 struct QSEECom_ion_fd_info ion_fd_info;
483 struct qcom_km_ion_info_t ihandle;
484 struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
485 int ret = 0;
486
487 handle = (struct QSEECom_handle *)(km_handle->qseecom);
488 ihandle.ion_fd = 0;
489 ihandle.ion_alloc_handle.handle = NULL;
490 if (qcom_km_ION_memalloc(&ihandle, dataLength) < 0) {
491 ALOGE("ION allocation failed");
492 return -1;
493 }
494 memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));
495
496 /* Populate the send data structure */
497 ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
498 ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) +
499 sizeof(qcom_km_key_blob_t) + sizeof(keymaster_rsa_sign_params_t);
500
501 send_cmd = (keymaster_sign_data_cmd_t *)handle->ion_sbuffer;
502 resp = (keymaster_sign_data_resp_t *)(handle->ion_sbuffer +
503 QSEECOM_ALIGN(sizeof(keymaster_sign_data_cmd_t)));
504 send_cmd->cmd_id = KEYMASTER_SIGN_DATA ;
505 send_cmd->sign_param.digest_type = sign_params->digest_type;
506 send_cmd->sign_param.padding_type = sign_params->padding_type;
507 memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength);
508 memcpy((unsigned char *)ihandle.ion_sbuffer, data, dataLength);
509
510 send_cmd->data = (uint32_t)ihandle.ion_sbuffer;
511 send_cmd->dlen = dataLength;
512 resp->sig_len = KM_KEY_SIZE_MAX;
513 resp->status = KEYMASTER_FAILURE;
514
515 ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
516 QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
517 QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);
518 if ( (ret < 0) || (resp->status < 0)) {
519 ALOGE("Sign data command failed resp->status = %d ret =%d", resp->status, ret);
520 qcom_km_ion_dealloc(&ihandle);
521 return -1;
522 } else {
523 UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(resp->sig_len)));
524 if (signedDataPtr.get() == NULL) {
525 ALOGE("Sign data memory allocation failed");
526 qcom_km_ion_dealloc(&ihandle);
527 return -1;
528 }
529 unsigned char* p = signedDataPtr.get();
530 memcpy(p, (unsigned char *)(&resp->signed_data), resp->sig_len);
531
532 *signedDataLength = resp->sig_len;
533 *signedData = signedDataPtr.release();
534 }
535 qcom_km_ion_dealloc(&ihandle);
536 return 0;
537}
538
539static int qcom_km_verify_data(const keymaster_device_t* dev,
540 const void* params,
541 const uint8_t* keyBlob, const size_t keyBlobLength,
542 const uint8_t* signedData, const size_t signedDataLength,
543 const uint8_t* signature, const size_t signatureLength)
544{
545 if (dev->context == NULL) {
546 ALOGE("qcom_km_verify_data: Context == NULL");
547 return -1;
548 }
549
550 if (signedData == NULL || signature == NULL) {
551 ALOGE("data or signature buffers == NULL");
552 return -1;
553 }
554
555 keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
556 if (sign_params->digest_type != DIGEST_NONE) {
557 ALOGE("Cannot handle digest type %d", sign_params->digest_type);
558 return -1;
559 } else if (sign_params->padding_type != PADDING_NONE) {
560 ALOGE("Cannot handle padding type %d", sign_params->padding_type);
561 return -1;
562 } else if (signatureLength != signedDataLength) {
563 ALOGE("signed data length must be signature length");
564 return -1;
565 }
566
567 struct QSEECom_handle *handle = NULL;
568 keymaster_verify_data_cmd_t *send_cmd = NULL;
569 keymaster_verify_data_resp_t *resp = NULL;
570
571 struct QSEECom_ion_fd_info ion_fd_info;
572 struct qcom_km_ion_info_t ihandle;
573 struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
574 int ret = 0;
575
576 handle = (struct QSEECom_handle *)(km_handle->qseecom);
577 ihandle.ion_fd = 0;
578 ihandle.ion_alloc_handle.handle = NULL;
579 if (qcom_km_ION_memalloc(&ihandle, signedDataLength + signatureLength) <0) {
580 ALOGE("ION allocation failed");
581 return -1;
582 }
583 memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));
584
585 /* Populate the send data structure */
586 ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
587 ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) +
588 sizeof(qcom_km_key_blob_t ) + sizeof(keymaster_rsa_sign_params_t);
589
590 send_cmd = (keymaster_verify_data_cmd_t *)handle->ion_sbuffer;
591 resp = (keymaster_verify_data_resp_t *)((char *)handle->ion_sbuffer +
592 sizeof(keymaster_verify_data_cmd_t));
593 send_cmd->cmd_id = KEYMASTER_VERIFY_DATA ;
594 send_cmd->sign_param.digest_type = sign_params->digest_type;
595 send_cmd->sign_param.padding_type = sign_params->padding_type;
596 memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength);
597
598 send_cmd->signed_data = (uint32_t)ihandle.ion_sbuffer;
599 send_cmd->signed_dlen = signedDataLength;
600 memcpy((unsigned char *)ihandle.ion_sbuffer, signedData, signedDataLength);
601
602 send_cmd->signature = signedDataLength;
603 send_cmd->slen = signatureLength;
604 memcpy(((unsigned char *)ihandle.ion_sbuffer + signedDataLength),
605 signature, signatureLength);
606 resp->status = KEYMASTER_FAILURE;
607 ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
608 QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
609 QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);
610
611 if ( (ret < 0) || (resp->status < 0)) {
612 ALOGE("Verify data command failed resp->status = %d ret =%d", resp->status, ret);
613 qcom_km_ion_dealloc(&ihandle);
614 return -1;
615 }
616 qcom_km_ion_dealloc(&ihandle);
617 return 0;
618}
619
620/* Close an opened OpenSSL instance */
621static int qcom_km_close(hw_device_t *dev)
622{
623 keymaster_device_t* km_dev = (keymaster_device_t *)dev;
624 struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)km_dev->context;
625
626 if (km_handle->qseecom == NULL) {
627 ALOGE("Context == NULL");
628 return -1;
629 }
630 (*km_handle->QSEECom_shutdown_app)((struct QSEECom_handle **)&km_handle->qseecom);
631 free(km_dev->context);
632 free(dev);
633 return 0;
634}
635
636static int qcom_km_get_lib_sym(qcom_keymaster_handle_t* km_handle)
637{
638 km_handle->libhandle = dlopen("/system/lib/libQSEEComAPI.so", RTLD_NOW);
639 if ( km_handle->libhandle ) {
640 *(void **)(&km_handle->QSEECom_start_app) =
641 dlsym(km_handle->libhandle,"QSEECom_start_app");
642 if (km_handle->QSEECom_start_app == NULL) {
643 ALOGE("dlsym: Error Loading QSEECom_start_app");
644 dlclose(km_handle->libhandle );
645 km_handle->libhandle = NULL;
646 return -1;
647 }
648 *(void **)(&km_handle->QSEECom_shutdown_app) =
649 dlsym(km_handle->libhandle,"QSEECom_shutdown_app");
650 if (km_handle->QSEECom_shutdown_app == NULL) {
651 ALOGE("dlsym: Error Loading QSEECom_shutdown_app");
652 dlclose(km_handle->libhandle );
653 km_handle->libhandle = NULL;
654 return -1;
655 }
656 *(void **)(&km_handle->QSEECom_send_cmd) =
657 dlsym(km_handle->libhandle,"QSEECom_send_cmd");
658 if (km_handle->QSEECom_send_cmd == NULL) {
659 ALOGE("dlsym: Error Loading QSEECom_send_cmd");
660 dlclose(km_handle->libhandle );
661 km_handle->libhandle = NULL;
662 return -1;
663 }
664 *(void **)(&km_handle->QSEECom_send_modified_cmd) =
665 dlsym(km_handle->libhandle,"QSEECom_send_modified_cmd");
666 if (km_handle->QSEECom_send_modified_cmd == NULL) {
667 ALOGE("dlsym: Error Loading QSEECom_send_modified_cmd");
668 dlclose(km_handle->libhandle );
669 km_handle->libhandle = NULL;
670 return -1;
671 }
672 } else {
673 ALOGE("failed to load qseecom library");
674 return -1;
675 }
676 return 0;
677}
678
679/*
680 * Generic device handling
681 */
682static int qcom_km_open(const hw_module_t* module, const char* name,
683 hw_device_t** device)
684{
685 int ret = 0;
686 qcom_keymaster_handle_t* km_handle;
687 if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
688 return -EINVAL;
689
690 km_handle = (qcom_keymaster_handle_t *)malloc(sizeof(qcom_keymaster_handle_t));
691 if (km_handle == NULL) {
692 ALOGE("Memalloc for keymaster handle failed");
693 return -1;
694 }
695 km_handle->qseecom = NULL;
696 km_handle->libhandle = NULL;
697 ret = qcom_km_get_lib_sym(km_handle);
698 if (ret) {
699 free(km_handle);
700 return -1;
701 }
702 Unique_keymaster_device_t dev(new keymaster_device_t);
703 if (dev.get() == NULL){
704 free(km_handle);
705 return -ENOMEM;
706 }
707 dev->context = (void *)km_handle;
708 ret = (*km_handle->QSEECom_start_app)((struct QSEECom_handle **)&km_handle->qseecom,
709 "/vendor/firmware/keymaster", "keymaster", 4096);
710 if (ret) {
711 ALOGE("Loading keymaster app failied");
712 free(km_handle);
713 return -1;
714 }
715 dev->common.tag = HARDWARE_DEVICE_TAG;
716 dev->common.version = 1;
717 dev->common.module = (struct hw_module_t*) module;
718 dev->common.close = qcom_km_close;
719 dev->flags = 0;
720
721 dev->generate_keypair = qcom_km_generate_keypair;
722 dev->import_keypair = qcom_km_import_keypair;
723 dev->get_keypair_public = qcom_km_get_keypair_public;
724 dev->delete_keypair = NULL;
725 dev->delete_all = NULL;
726 dev->sign_data = qcom_km_sign_data;
727 dev->verify_data = qcom_km_verify_data;
728
729 *device = reinterpret_cast<hw_device_t*>(dev.release());
730
731 return 0;
732}
733
734static struct hw_module_methods_t keystore_module_methods = {
735 open: qcom_km_open,
736};
737
738struct keystore_module HAL_MODULE_INFO_SYM
739__attribute__ ((visibility ("default"))) = {
740 common: {
741 tag: HARDWARE_MODULE_TAG,
742 version_major: 1,
743 version_minor: 0,
744 id: KEYSTORE_HARDWARE_MODULE_ID,
745 name: "Keymaster QCOM HAL",
746 author: "The Android Open Source Project",
747 methods: &keystore_module_methods,
748 dso: 0,
749 reserved: {},
750 },
751};