• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
22 
23 #include <hardware/hardware.h>
24 #include <hardware/keymaster0.h>
25 
26 #include <openssl/evp.h>
27 #include <openssl/bio.h>
28 #include <openssl/rsa.h>
29 #include <openssl/err.h>
30 #include <openssl/x509.h>
31 
32 #include <linux/ioctl.h>
33 #include <linux/msm_ion.h>
34 #include <sys/mman.h>
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stddef.h>
39 #include <unistd.h>
40 #include <dirent.h>
41 #include <fcntl.h>
42 
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <dlfcn.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 {
operator ()EVP_PKEY_Delete79     void operator()(EVP_PKEY* p) const {
80         EVP_PKEY_free(p);
81     }
82 };
83 typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
84 
85 struct RSA_Delete {
operator ()RSA_Delete86     void operator()(RSA* p) const {
87         RSA_free(p);
88     }
89 };
90 typedef std::unique_ptr<RSA, RSA_Delete> Unique_RSA;
91 
92 typedef std::unique_ptr<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 
qcom_km_get_keypair_public(const keymaster0_device_t * dev,const uint8_t * keyBlob,const size_t keyBlobLength,uint8_t ** x509_data,size_t * x509_data_length)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     std::unique_ptr<unsigned char[]> key(new unsigned char[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 = 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 
qcom_km_ION_memalloc(struct qcom_km_ion_info_t * handle,uint32_t size)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  */
qcom_km_ion_dealloc(struct qcom_km_ion_info_t * handle)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 
qcom_km_generate_keypair(const keymaster0_device_t * dev,const keymaster_keypair_t key_type,const void * key_params,uint8_t ** keyBlob,size_t * keyBlobLength)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         std::unique_ptr<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 
qcom_km_import_keypair(const keymaster0_device_t * dev,const uint8_t * key,const size_t key_length,uint8_t ** keyBlob,size_t * keyBlobLength)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         std::unique_ptr<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 
qcom_km_sign_data(const keymaster0_device_t * dev,const void * params,const uint8_t * keyBlob,const size_t keyBlobLength,const uint8_t * data,const size_t dataLength,uint8_t ** signedData,size_t * signedDataLength)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         std::unique_ptr<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 
qcom_km_verify_data(const keymaster0_device_t * dev,const void * params,const uint8_t * keyBlob,const size_t keyBlobLength,const uint8_t * signedData,const size_t signedDataLength,const uint8_t * signature,const size_t signatureLength)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 */
qcom_km_close(hw_device_t * dev)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 
qcom_km_get_lib_sym(qcom_keymaster_handle_t * km_handle)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  */
qcom_km_open(const hw_module_t * module,const char * name,hw_device_t ** device)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