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