int fpc_load_user_db(char* path) { FILE *f = fopen(path, "r"); if (f == NULL) { ALOGE("Error opening file : %s", path); return -1; } fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); ALOGI("Loading DB of size : %ld", fsize); struct qcom_km_ion_info_t ihandle; struct QSEECom_ion_fd_info ion_fd_info; if (qcom_km_ION_memalloc(&ihandle, fsize) <0) { ALOGE("ION allocation failed"); return -1; } fread(ihandle.ion_sbuffer, fsize, 1, f); fclose(f); fpc_send_mod_cmd_t* send_cmd = (fpc_send_mod_cmd_t*) mHandle->ion_sbuffer; fpc_send_std_cmd_t* rec_cmd = (fpc_send_std_cmd_t*) mHandle->ion_sbuffer + 64; memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = 4; send_cmd->cmd_id = FPC_SET_DB_DATA; send_cmd->v_addr = (intptr_t) ihandle.ion_sbuffer; send_cmd->length = fsize; send_cmd->extra = 0x00; int ret = send_modified_cmd_fn(mHandle,send_cmd,64,rec_cmd,64,&ion_fd_info); if(ret < 0) { qcom_km_ion_dealloc(&ihandle); return -1; } if (send_cmd->v_addr != 0) { ALOGE("Error on TZ\n"); qcom_km_ion_dealloc(&ihandle); return -1; } qcom_km_ion_dealloc(&ihandle); return 0; }
int fpc_store_user_db(uint32_t length, char* path) { fpc_send_mod_cmd_t* send_cmd = (fpc_send_mod_cmd_t*) mHandle->ion_sbuffer; fpc_send_std_cmd_t* rec_cmd = (fpc_send_std_cmd_t*) mHandle->ion_sbuffer + 64; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; ihandle.ion_fd = 0; if (qcom_km_ION_memalloc(&ihandle, length) <0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = 4; send_cmd->cmd_id = FPC_GET_DB_DATA; send_cmd->v_addr = (intptr_t) ihandle.ion_sbuffer; send_cmd->length = length; send_cmd->extra = 0x00; memset((unsigned char *)ihandle.ion_sbuffer, 0, length); int ret = send_modified_cmd_fn(mHandle,send_cmd,64,rec_cmd,64,&ion_fd_info); if(ret < 0) { qcom_km_ion_dealloc(&ihandle); return -1; } if (send_cmd->v_addr != 0) { ALOGE("Error on TZ\n"); qcom_km_ion_dealloc(&ihandle); return -1; } FILE *f = fopen(path, "w"); if (f == NULL) { ALOGE("Error opening file : %s", path); return -1; } fwrite(ihandle.ion_sbuffer, length, 1, f); fclose(f); qcom_km_ion_dealloc(&ihandle); return 0; }
int fpc_get_hw_auth_obj(void * buffer, int length) { fpc_send_mod_cmd_t* send_cmd = (fpc_send_mod_cmd_t*) mHandle->ion_sbuffer; fpc_send_std_cmd_t* rec_cmd = (fpc_send_std_cmd_t*) mHandle->ion_sbuffer + 64; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; ihandle.ion_fd = 0; if (qcom_km_ION_memalloc(&ihandle, length) <0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = 4; send_cmd->cmd_id = FPC_GET_AUTH_HAT; send_cmd->v_addr = (intptr_t) ihandle.ion_sbuffer; send_cmd->length = length; send_cmd->extra = 0x00; memset((unsigned char *)ihandle.ion_sbuffer, 0, length); int ret = send_modified_cmd_fn(mHandle,send_cmd,64,rec_cmd,64,&ion_fd_info); memcpy(buffer, (unsigned char *)ihandle.ion_sbuffer, length); if(ret < 0) { qcom_km_ion_dealloc(&ihandle); return -1; } if (send_cmd->v_addr != 0) { ALOGE("Error on TZ\n"); qcom_km_ion_dealloc(&ihandle); return -1; } qcom_km_ion_dealloc(&ihandle); return 0; }
int send_modified_command_to_tz(uint32_t cmd, struct QSEECom_handle * handle, void * buffer, uint32_t len) { fpc_send_mod_cmd_t* send_cmd = (fpc_send_mod_cmd_t*) handle->ion_sbuffer; fpc_send_std_cmd_t* rec_cmd = (fpc_send_std_cmd_t*) handle->ion_sbuffer + 64; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; ihandle.ion_fd = 0; if (qcom_km_ION_memalloc(&ihandle, len) <0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = 4; send_cmd->cmd_id = cmd; send_cmd->v_addr = (intptr_t) ihandle.ion_sbuffer; send_cmd->length = len; send_cmd->extra = 0x00; memcpy((unsigned char *)ihandle.ion_sbuffer, buffer, len); int ret = send_modified_cmd_fn(handle,send_cmd,64,rec_cmd,64,&ion_fd_info); if(ret < 0) { qcom_km_ion_dealloc(&ihandle); return -1; } if (send_cmd->v_addr != 0) { ALOGE("Error on TZ\n"); qcom_km_ion_dealloc(&ihandle); return -1; } qcom_km_ion_dealloc(&ihandle); return 0; }
static int qcom_km_verify_data(const keymaster_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) { if (dev->context == NULL) { ALOGE("qcom_km_verify_data: Context == NULL"); return -1; } if (signedData == NULL || signature == NULL) { ALOGE("data or signature buffers == NULL"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGE("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGE("Cannot handle padding type %d", sign_params->padding_type); return -1; } else if (signatureLength != signedDataLength) { ALOGE("signed data length must be signature length"); return -1; } struct QSEECom_handle *handle = NULL; keymaster_verify_data_cmd_t *send_cmd = NULL; keymaster_verify_data_resp_t *resp = NULL; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context; int ret = 0; handle = (struct QSEECom_handle *)(km_handle->qseecom); ihandle.ion_fd = 0; ihandle.ion_alloc_handle.handle = NULL; if (qcom_km_ION_memalloc(&ihandle, signedDataLength + signatureLength) <0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); /* Populate the send data structure */ ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) + sizeof(qcom_km_key_blob_t ) + sizeof(keymaster_rsa_sign_params_t); send_cmd = (keymaster_verify_data_cmd_t *)handle->ion_sbuffer; resp = (keymaster_verify_data_resp_t *)((char *)handle->ion_sbuffer + sizeof(keymaster_verify_data_cmd_t)); send_cmd->cmd_id = KEYMASTER_VERIFY_DATA ; send_cmd->sign_param.digest_type = sign_params->digest_type; send_cmd->sign_param.padding_type = sign_params->padding_type; memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength); send_cmd->signed_data = (uint32_t)ihandle.ion_sbuffer; send_cmd->signed_dlen = signedDataLength; memcpy((unsigned char *)ihandle.ion_sbuffer, signedData, signedDataLength); send_cmd->signature = signedDataLength; send_cmd->slen = signatureLength; memcpy(((unsigned char *)ihandle.ion_sbuffer + signedDataLength), signature, signatureLength); resp->status = KEYMASTER_FAILURE; ret = (*km_handle->QSEECom_set_bandwidth)(handle, true); if (ret < 0) { ALOGE("Verify data command failed (unable to enable clks) ret =%d", ret); qcom_km_ion_dealloc(&ihandle); return -1; } ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info); if((*km_handle->QSEECom_set_bandwidth)(handle, false)) ALOGE("Verify data command: (unable to disable clks)"); if ( (ret < 0) || (resp->status < 0)) { ALOGE("Verify data command failed resp->status = %d ret =%d", resp->status, ret); qcom_km_ion_dealloc(&ihandle); return -1; } qcom_km_ion_dealloc(&ihandle); return 0; }
static int qcom_km_sign_data(const keymaster_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) { if (dev->context == NULL) { ALOGE("qcom_km_sign_data: Context == NULL"); return -1; } if (dataLength > KM_KEY_SIZE_MAX) { ALOGE("Input data to be signed is too long %d bytes", dataLength); return -1; } if (data == NULL) { ALOGE("input data to sign == NULL"); return -1; } else if (signedData == NULL || signedDataLength == NULL) { ALOGE("Output signature buffer == NULL"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGE("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGE("Cannot handle padding type %d", sign_params->padding_type); return -1; } struct QSEECom_handle *handle = NULL; keymaster_sign_data_cmd_t *send_cmd = NULL; keymaster_sign_data_resp_t *resp = NULL; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context; int ret = 0; handle = (struct QSEECom_handle *)(km_handle->qseecom); ihandle.ion_fd = 0; ihandle.ion_alloc_handle.handle = NULL; if (qcom_km_ION_memalloc(&ihandle, dataLength) < 0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); /* Populate the send data structure */ ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) + sizeof(qcom_km_key_blob_t) + sizeof(keymaster_rsa_sign_params_t); send_cmd = (keymaster_sign_data_cmd_t *)handle->ion_sbuffer; resp = (keymaster_sign_data_resp_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(keymaster_sign_data_cmd_t))); send_cmd->cmd_id = KEYMASTER_SIGN_DATA ; send_cmd->sign_param.digest_type = sign_params->digest_type; send_cmd->sign_param.padding_type = sign_params->padding_type; memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength); memcpy((unsigned char *)ihandle.ion_sbuffer, data, dataLength); send_cmd->data = (uint32_t)ihandle.ion_sbuffer; send_cmd->dlen = dataLength; resp->sig_len = KM_KEY_SIZE_MAX; resp->status = KEYMASTER_FAILURE; ret = (*km_handle->QSEECom_set_bandwidth)(handle, true); if (ret < 0) { ALOGE("Sign data command failed (unable to enable clks) ret =%d", ret); qcom_km_ion_dealloc(&ihandle); return -1; } ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info); if((*km_handle->QSEECom_set_bandwidth)(handle, false)) ALOGE("Sign data command: (unable to disable clks)"); if ( (ret < 0) || (resp->status < 0)) { ALOGE("Sign data command failed resp->status = %d ret =%d", resp->status, ret); qcom_km_ion_dealloc(&ihandle); return -1; } else { UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(resp->sig_len))); if (signedDataPtr.get() == NULL) { ALOGE("Sign data memory allocation failed"); qcom_km_ion_dealloc(&ihandle); return -1; } unsigned char* p = signedDataPtr.get(); memcpy(p, (unsigned char *)(&resp->signed_data), resp->sig_len); *signedDataLength = resp->sig_len; *signedData = signedDataPtr.release(); } qcom_km_ion_dealloc(&ihandle); return 0; }
static int qcom_km_import_keypair(const keymaster_device_t* dev, const uint8_t* key, const size_t key_length, uint8_t** keyBlob, size_t* keyBlobLength) { if (dev->context == NULL) { ALOGE("qcom_km_import_keypair: Context == NULL"); return -1; } if (key == NULL) { ALOGE("Input key == NULL"); return -1; } else if (keyBlob == NULL || keyBlobLength == NULL) { ALOGE("Output key blob or length == NULL"); return -1; } struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; int ret = 0; ihandle.ion_fd = 0; ihandle.ion_alloc_handle.handle = NULL; if (qcom_km_ION_memalloc(&ihandle, QSEECOM_ALIGN(key_length)) < 0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); /* Populate the send data structure */ ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t); struct QSEECom_handle *handle = NULL; keymaster_import_keypair_cmd_t *send_cmd = NULL; keymaster_import_keypair_resp_t *resp = NULL; struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context; handle = (struct QSEECom_handle *)(km_handle->qseecom); send_cmd = (keymaster_import_keypair_cmd_t *)handle->ion_sbuffer; resp = (keymaster_import_keypair_resp_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(keymaster_import_keypair_cmd_t))); send_cmd->cmd_id = KEYMASTER_IMPORT_KEYPAIR; send_cmd->pkcs8_key = (uint32_t)ihandle.ion_sbuffer; memcpy((unsigned char *)ihandle.ion_sbuffer, key, key_length); send_cmd->pkcs8_key_len = key_length; resp->status = KEYMASTER_FAILURE; resp->key_blob_len = sizeof(qcom_km_key_blob_t); ret = (*km_handle->QSEECom_set_bandwidth)(handle, true); if (ret < 0) { ALOGE("Import key command failed (unable to enable clks) ret =%d", ret); qcom_km_ion_dealloc(&ihandle); return -1; } ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info); if((*km_handle->QSEECom_set_bandwidth)(handle, false)) ALOGE("Import key command: (unable to disable clks)"); if ( (ret < 0) || (resp->status < 0)) { ALOGE("Import key command failed resp->status = %d ret =%d", resp->status, ret); qcom_km_ion_dealloc(&ihandle); return -1; } else { UniquePtr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]); if (keydata.get() == NULL) { ALOGE("could not allocate memory for key blob"); return -1; } unsigned char* p = keydata.get(); memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len); *keyBlob = keydata.release(); *keyBlobLength = resp->key_blob_len; } qcom_km_ion_dealloc(&ihandle); return 0; }