Home | History | Annotate | Download | only in keymaster
      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 <nativehelper/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>
     55 struct 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 
     63 struct 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 };
     76 typedef struct qcom_keymaster_handle qcom_keymaster_handle_t;
     77 
     78 struct EVP_PKEY_Delete {
     79     void operator()(EVP_PKEY* p) const {
     80         EVP_PKEY_free(p);
     81     }
     82 };
     83 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
     84 
     85 struct RSA_Delete {
     86     void operator()(RSA* p) const {
     87         RSA_free(p);
     88     }
     89 };
     90 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
     91 
     92 typedef 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 
    102 static 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 
    192 static 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 
    268 map_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 
    275 ioctl_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 
    284 alloc_fail:
    285     if (ion_fd > 0)
    286        close(ion_fd);
    287     return ret;
    288 }
    289 
    290 /** @brief: Deallocate ION memory
    291  *
    292  *
    293  */
    294 static 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 
    315 static 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 
    384 static 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 
    469 static 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 
    570 static 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 */
    663 static 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 
    678 static 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  */
    733 static 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 
    785 static struct hw_module_methods_t keystore_module_methods = {
    786     .open = qcom_km_open,
    787 };
    788 
    789 struct 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