📄 vtpm_manager_handler.c
字号:
// ===================================================================// // Copyright (c) 2005, Intel Corp.// All rights reserved.//// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met://// * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution.// * Neither the name of Intel Corporation nor the names of its // contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED// OF THE POSSIBILITY OF SUCH DAMAGE.// ===================================================================// // vtpm_manager_handler.c// // This file will house the main logic of the VTPM Manager//// ==================================================================#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>#include "vtpm_manager.h"#include "vtpmpriv.h"#include "vtsp.h"#include "bsg.h"#include "hashtable.h"#include "hashtable_itr.h"#include "log.h"#include "buffer.h"#define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%s]: " fmt, thread_name, ##args );#define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );#define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args );// ---------------------- Prototypes -------------------TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, TPM_COMMAND_CODE ord, buffer_t *command_buf, buffer_t *result_buf, BOOL is_priv, char *thread_name);TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, VTPM_DMI_RESOURCE *dmi_res, BYTE *cmd_header, buffer_t *param_buf, buffer_t *result_buf, char *thread_name);TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, BOOL fw_tpm, // Forward TPM cmds? vtpm_ipc_handle_t *fw_tx_ipc_h, vtpm_ipc_handle_t *fw_rx_ipc_h, BOOL is_priv, char *thread_name) { TPM_RESULT status = TPM_FAIL; // Should never return UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size; BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply; buffer_t *command_buf=NULL, *result_buf=NULL; TPM_TAG tag; TPM_COMMAND_CODE ord; VTPM_DMI_RESOURCE *dmi_res; int size_read, size_write, i; BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); command_buf = (buffer_t *) malloc(sizeof(buffer_t)); result_buf = (buffer_t *) malloc(sizeof(buffer_t)); // ------------------------ Main Loop -------------------------------- while(1) { vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name); // --------------------- Read Cmd from Sender ---------------- // Read command header size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); if (size_read > 0) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read); for (i=0; i<size_read; i++) vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); } else { vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono = %d. Aborting... \n", thread_name, errno); goto abort_command; } if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n"); vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read); goto abort_command; } // Unpack header BSG_UnpackList(cmd_header, 4, BSG_TYPE_UINT32, &dmi, BSG_TPM_TAG, &tag, BSG_TYPE_UINT32, &in_param_size, BSG_TPM_COMMAND_CODE, &ord ); // Using the header info, read the parameters of the command // Note that in_param_size is in the client's context cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT; if (cmd_size > 0) { in_param = (BYTE *) malloc(cmd_size); size_read = vtpm_ipc_read( rx_ipc_h, NULL, in_param, cmd_size); if (size_read > 0) { for (i=0; i<size_read; i++) vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); } else { vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error reading cmd from ipc. Aborting... \n", thread_name); goto abort_command; } vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); if (size_read < (int) cmd_size) { vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size); goto abort_command; } } else { in_param = NULL; vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); } // Init the buffers used to handle the command and the response if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) || (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); goto abort_command; } // -------------- Dispatch Commands to Handlers ----------- if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) { vtpm_lock_wrlock(); } else { vtpm_lock_rdlock(); } if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) || (!dmi_res->connected) ) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi); status = TPM_BAD_PARAMETER; // We have no one to reply to, they don't exist. goto abort_command; } if (tag == VTPM_TAG_REQ) { status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name); } else { // This is not a VTPM Command at all. if (fw_tpm) { status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name); // This means calling the DMI failed, not that the cmd failed in the DMI // Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app if (status != TPM_SUCCESS) { status = TPM_IOERROR; goto abort_with_error; } // Unlike all other commands, forwarded commands yield a result_buf that includes the DMI's status. This // should be forwarded to the caller VM add_header = FALSE; } else { // We are not supposed to forward TPM commands at all. int i; vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n"); vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord); for (i=0; i<cmd_size; i++) vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); status = TPM_FAIL; goto abort_with_error; } } // end else for is VTPM Command // ------------------- Respond to Sender ------------------ // Errors while handling responses jump here to reply with error messages // NOTE: Currently there are no recoverable errors in multi-VM mode. If one // is added to the code, this ifdef should be removed. // Also note this is NOT referring to errors in commands, but rather // this is about I/O errors and such.#ifndef VTPM_MULTI_VM abort_with_error:#endif if (add_header) { // Prepend VTPM header with destination DM stamped out_param_size = buffer_len(result_buf); out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; out_message = (BYTE *) malloc (reply_size); reply = out_message; BSG_PackList(out_message, 4, BSG_TYPE_UINT32, (BYTE *) &dmi, BSG_TPM_TAG, (BYTE *) &tag, BSG_TYPE_UINT32, (BYTE *) &out_message_size, BSG_TPM_RESULT, (BYTE *) &status); if (buffer_len(result_buf) > 0) memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); //Note: Send message + dmi_id } else { reply = result_buf->bytes; reply_size = buffer_len(result_buf); } size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size ); if (size_write > 0) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); for (i=0; i < reply_size; i++) vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]); vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -