static void setup_cmd_rsp_buffers(struct qseecom_handle *handle, void **cmd, int *cmd_len, void **resp, int *resp_len) { *cmd = handle->sbuf; if (*cmd_len & QSEECOM_ALIGN_MASK) *cmd_len = QSEECOM_ALIGN(*cmd_len); *resp = handle->sbuf + *cmd_len; if (*resp_len & QSEECOM_ALIGN_MASK) *resp_len = QSEECOM_ALIGN(*resp_len); }
int derive_keys_from_session_key(struct qcom_wv_handle* handle, int ctx_id, uint32_t enc_session_key_length, uint32_t mac_key_context_length, uint32_t enc_key_context_length) { //Initializing the request and response buffers uint32_t cmd_req_size = QSEECOM_ALIGN(61460); uint32_t cmd_resp_size = QSEECOM_ALIGN(8); uint32_t* cmd_req = malloc(cmd_req_size); uint32_t* cmd_resp = malloc(cmd_resp_size); memset(cmd_req, 0, cmd_req_size); memset(cmd_resp, 0, cmd_resp_size); cmd_req[0] = OEMCrypto_DeriveKeysFromSessionKey; cmd_req[1] = ctx_id; //ctxId cmd_req[0x5008/sizeof(uint32_t)] = enc_session_key_length; //enc_session_key_length cmd_req[0xA00C/sizeof(uint32_t)] = mac_key_context_length; //mac_key_context_length cmd_req[0xF010/sizeof(uint32_t)] = enc_key_context_length; //enc_key_context_length int res = (*handle->QSEECom_set_bandwidth)(handle->qseecom, true); if (res < 0) { free(cmd_req); free(cmd_resp); perror("[-] Unable to enable clks"); return -errno; } res = (*handle->QSEECom_send_cmd)(handle->qseecom, cmd_req, cmd_req_size, cmd_resp, cmd_resp_size); if ((*handle->QSEECom_set_bandwidth)(handle->qseecom, false)) { perror("[-] Import key command: (unable to disable clks)"); } res = (int)cmd_resp[1]; free(cmd_req); free(cmd_resp); return res; }
int generate_nonce(struct qcom_wv_handle* handle, int ctx_id, uint32_t* nonce) { //Initializing the request and response buffers uint32_t cmd_req_size = QSEECOM_ALIGN(0x8); uint32_t cmd_resp_size = QSEECOM_ALIGN(0xC); uint32_t* cmd_req = malloc(cmd_req_size); uint32_t* cmd_resp = malloc(cmd_resp_size); memset(cmd_req, 0, cmd_req_size); memset(cmd_resp, 0, cmd_resp_size); cmd_req[0] = OEMCrypto_GenerateNonce; cmd_req[1] = ctx_id; int res = (*handle->QSEECom_set_bandwidth)(handle->qseecom, true); if (res < 0) { free(cmd_req); free(cmd_resp); perror("[-] Unable to enable clks"); return -errno; } res = (*handle->QSEECom_send_cmd)(handle->qseecom, cmd_req, cmd_req_size, cmd_resp, cmd_resp_size); if ((*handle->QSEECom_set_bandwidth)(handle->qseecom, false)) { perror("[-] Import key command: (unable to disable clks)"); } res = (int)cmd_resp[2]; *nonce = cmd_resp[1]; free(cmd_req); free(cmd_resp); return res; }
int send_cmd_1026(struct qcom_wv_handle* handle) { //Initializing the request and response buffers uint32_t cmd_req_size = QSEECOM_ALIGN(4); uint32_t cmd_resp_size = QSEECOM_ALIGN(0xC); uint32_t* cmd_req = malloc(cmd_req_size); uint32_t* cmd_resp = malloc(cmd_resp_size); memset(cmd_req, 0, cmd_req_size); memset(cmd_resp, 0, cmd_resp_size); cmd_req[0] = 1026; int res = (*handle->QSEECom_set_bandwidth)(handle->qseecom, true); if (res < 0) { free(cmd_req); free(cmd_resp); perror("[-] Unable to enable clks"); return -errno; } res = (*handle->QSEECom_send_cmd)(handle->qseecom, cmd_req, cmd_req_size, cmd_resp, cmd_resp_size); if ((*handle->QSEECom_set_bandwidth)(handle->qseecom, false)) { perror("[-] Import key command: (unable to disable clks)"); } res = (int)cmd_resp[1]; free(cmd_req); free(cmd_resp); return res; }
int close_session(struct qcom_wv_handle* handle, int ctx_id) { //Initializing the request and response buffers uint32_t cmd_req_size = QSEECOM_ALIGN(8); uint32_t cmd_resp_size = QSEECOM_ALIGN(8); uint32_t* cmd_req = malloc(cmd_req_size); uint32_t* cmd_resp = malloc(cmd_resp_size); memset(cmd_req, 0, cmd_req_size); memset(cmd_resp, 0, cmd_resp_size); //Filling in the data in the request buffer cmd_req[0] = OEMCrypto_CloseSession; cmd_req[1] = ctx_id; //ctxId int res = (*handle->QSEECom_set_bandwidth)(handle->qseecom, true); if (res < 0) { free(cmd_req); free(cmd_resp); perror("[-] Unable to enable clks"); return -errno; } res = (*handle->QSEECom_send_cmd)(handle->qseecom, cmd_req, cmd_req_size, cmd_resp, cmd_resp_size); if ((*handle->QSEECom_set_bandwidth)(handle->qseecom, false)) { perror("[-] Import key command: (unable to disable clks)"); } free(cmd_req); free(cmd_resp); return res; }
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; }
static int qcom_km_generate_keypair(const keymaster_device_t* dev, const keymaster_keypair_t key_type, const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength) { if (dev->context == NULL) { ALOGE("qcom_km_generate_keypair: Context == NULL"); return -1; } if (key_type != TYPE_RSA) { ALOGE("Unsupported key type %d", key_type); return -1; } else if (key_params == NULL) { ALOGE("key_params == null"); return -1; } if (keyBlob == NULL || keyBlobLength == NULL) { ALOGE("output key blob or length == NULL"); return -1; } keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params; keymaster_gen_keypair_cmd_t *send_cmd = NULL; keymaster_gen_keypair_resp_t *resp = NULL; struct QSEECom_handle *handle = NULL; struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context; int ret = 0; handle = (struct QSEECom_handle *)(km_handle->qseecom); send_cmd = (keymaster_gen_keypair_cmd_t *)handle->ion_sbuffer; resp = (keymaster_gen_keypair_resp_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t))); send_cmd->cmd_id = KEYMASTER_GENERATE_KEYPAIR; send_cmd->key_type = key_type; send_cmd->rsa_params.modulus_size = rsa_params->modulus_size; send_cmd->rsa_params.public_exponent = rsa_params->public_exponent; 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("Generate key command failed (unable to enable clks) ret =%d", ret); return -1; } ret = (*km_handle->QSEECom_send_cmd)(handle, send_cmd, QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)), resp, QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_resp_t))); if((*km_handle->QSEECom_set_bandwidth)(handle, false)) ALOGE("Import key command: (unable to disable clks)"); if ( (ret < 0) || (resp->status < 0)) { ALOGE("Generate key command failed resp->status = %d ret =%d", resp->status, ret); 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; } return 0; }