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