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