/* * Copyright (c) 2013-2015 TRUSTONIC LIMITED * All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef MCP_H_ #define MCP_H_ #include "mci/mcloadformat.h" /** Indicates a response */ #define FLAG_RESPONSE BIT(31) /** Maximum number of buffers that can be mapped at once */ #define MCP_MAP_MAX_BUF 4 /** MobiCore Return Code Defines. * List of the possible MobiCore return codes. */ enum mcp_result { /** Memory has successfully been mapped */ MC_MCP_RET_OK = 0, /** The session ID is invalid */ MC_MCP_RET_ERR_INVALID_SESSION = 1, /** The UUID of the Trustlet is unknown */ MC_MCP_RET_ERR_UNKNOWN_UUID = 2, /** The ID of the driver is unknown */ MC_MCP_RET_ERR_UNKNOWN_DRIVER_ID = 3, /** No more session are allowed */ MC_MCP_RET_ERR_NO_MORE_SESSIONS = 4, /** The container is invalid */ MC_MCP_RET_ERR_CONTAINER_INVALID = 5, /** The Trustlet is invalid */ MC_MCP_RET_ERR_TRUSTLET_INVALID = 6, /** The memory block has already been mapped before */ MC_MCP_RET_ERR_ALREADY_MAPPED = 7, /** Alignment or length error in the command parameters */ MC_MCP_RET_ERR_INVALID_PARAM = 8, /** No space left in the virtual address space of the session */ MC_MCP_RET_ERR_OUT_OF_RESOURCES = 9, /** WSM type unknown or broken WSM */ MC_MCP_RET_ERR_INVALID_WSM = 10, /** unknown error */ MC_MCP_RET_ERR_UNKNOWN = 11, /** Length of map invalid */ MC_MCP_RET_ERR_INVALID_MAPPING_LENGTH = 12, /** Map can only be applied to Trustlet session */ MC_MCP_RET_ERR_MAPPING_TARGET = 13, /** Couldn't open crypto session */ MC_MCP_RET_ERR_OUT_OF_CRYPTO_RESOURCES = 14, /** System Trustlet signature verification failed */ MC_MCP_RET_ERR_SIGNATURE_VERIFICATION_FAILED = 15, /** System Trustlet public key is wrong */ MC_MCP_RET_ERR_WRONG_PUBLIC_KEY = 16, /** Wrong containter type(s) */ MC_MCP_RET_ERR_CONTAINER_TYPE_MISMATCH = 17, /** Container is locked (or not activated) */ MC_MCP_RET_ERR_CONTAINER_LOCKED = 18, /** SPID is not registered with root container */ MC_MCP_RET_ERR_SP_NO_CHILD = 19, /** UUID is not registered with sp container */ MC_MCP_RET_ERR_TL_NO_CHILD = 20, /** Unwrapping of root container failed */ MC_MCP_RET_ERR_UNWRAP_ROOT_FAILED = 21, /** Unwrapping of service provider container failed */ MC_MCP_RET_ERR_UNWRAP_SP_FAILED = 22, /** Unwrapping of Trustlet container failed */ MC_MCP_RET_ERR_UNWRAP_TRUSTLET_FAILED = 23, /** Container version mismatch */ MC_MCP_RET_ERR_CONTAINER_VERSION_MISMATCH = 24, /** Decryption of service provider trustlet failed */ MC_MCP_RET_ERR_SP_TL_DECRYPTION_FAILED = 25, /** Hash check of service provider trustlet failed */ MC_MCP_RET_ERR_SP_TL_HASH_CHECK_FAILED = 26, /** Activation/starting of task failed */ MC_MCP_RET_ERR_LAUNCH_TASK_FAILED = 27, /** Closing of task not yet possible, try again later */ MC_MCP_RET_ERR_CLOSE_TASK_FAILED = 28, /**< Service is blocked and a session cannot be opened to it */ MC_MCP_RET_ERR_SERVICE_BLOCKED = 29, /**< Service is locked and a session cannot be opened to it */ MC_MCP_RET_ERR_SERVICE_LOCKED = 30, /**< Service was forcefully killed (due to an administrative command) */ MC_MCP_RET_ERR_SERVICE_KILLED = 31, /** The command is unknown */ MC_MCP_RET_ERR_UNKNOWN_COMMAND = 50, /** The command data is invalid */ MC_MCP_RET_ERR_INVALID_DATA = 51 }; /** Possible MCP Command IDs * Command ID must be between 0 and 0x7FFFFFFF. */ enum cmd_id { /** Invalid command ID */ MC_MCP_CMD_ID_INVALID = 0x00, /** Open a session */ MC_MCP_CMD_OPEN_SESSION = 0x01, /** Close an existing session */ MC_MCP_CMD_CLOSE_SESSION = 0x03, /** Map WSM to session */ MC_MCP_CMD_MAP = 0x04, /** Unmap WSM from session */ MC_MCP_CMD_UNMAP = 0x05, /** Prepare for suspend */ MC_MCP_CMD_SUSPEND = 0x06, /** Resume from suspension */ MC_MCP_CMD_RESUME = 0x07, /** Get MobiCore version information */ MC_MCP_CMD_GET_MOBICORE_VERSION = 0x09, /** Close MCP and unmap MCI */ MC_MCP_CMD_CLOSE_MCP = 0x0A, /** Load token for device attestation */ MC_MCP_CMD_LOAD_TOKEN = 0x0B, /** Check that TA can be loaded */ MC_MCP_CMD_CHECK_LOAD_TA = 0x0C, /** Map multiple WSMs to session */ MC_MCP_CMD_MULTIMAP = 0x0D, /** Unmap multiple WSMs to session */ MC_MCP_CMD_MULTIUNMAP = 0x0E, }; /* * Types of WSM known to the MobiCore. */ #define WSM_TYPE_MASK 0xFF #define WSM_INVALID 0 /** Invalid memory type */ #define WSM_L2 2 /** Buffer mapping uses L2/L3 table */ #define WSM_L1 3 /** Buffer mapping uses fake L1 table */ /** Magic number used to identify if Open Command supports GP client * authentication. */ #define MC_GP_CLIENT_AUTH_MAGIC 0x47504131 /* "GPA1" */ /** Command header. * It just contains the command ID. Only values specified in cmd_id are * allowed as command IDs. If the command ID is unspecified the MobiCore * returns an empty response with the result set to * MC_MCP_RET_ERR_UNKNOWN_COMMAND. */ struct cmd_header { enum cmd_id cmd_id; /** Command ID of the command */ }; /** Response header. * MobiCore will reply to every MCP command with an MCP response. Like the MCP * command the response consists of a header followed by response data. The * response is written to the same memory location as the MCP command. */ struct rsp_header { uint32_t rsp_id; /** Command ID | FLAG_RESPONSE */ enum mcp_result result; /** Result of the command execution */ }; /** @defgroup CMD MCP Commands */ /** @defgroup ASMCMD Administrative Commands */ /** @defgroup MCPGETMOBICOREVERSION GET_MOBICORE_VERSION * Get MobiCore version info. * */ /** Get MobiCore Version Command */ struct cmd_get_version { struct cmd_header cmd_header; /** Command header */ }; /** Get MobiCore Version Command Response */ struct rsp_get_version { struct rsp_header rsp_header; /** Response header */ struct mc_version_info version_info; /** MobiCore version info */ }; /** @defgroup POWERCMD Power Management Commands */ /** @defgroup MCPSUSPEND SUSPEND * Prepare MobiCore suspension. * This command allows MobiCore and MobiCore drivers to release or clean * resources and save device state. * */ /** Suspend Command */ struct cmd_suspend { struct cmd_header cmd_header; /** Command header */ }; /** Suspend Command Response */ struct rsp_suspend { struct rsp_header rsp_header; /** Response header */ }; /** @defgroup MCPRESUME RESUME * Resume MobiCore from suspension. * This command allows MobiCore and MobiCore drivers to reinitialize hardware * affected by suspension. * */ /** Resume Command */ struct cmd_resume { struct cmd_header cmd_header; /** Command header */ }; /** Resume Command Response */ struct rsp_resume { struct rsp_header rsp_header; /** Response header */ }; /** @defgroup SESSCMD Session Management Commands */ /** @defgroup MCPOPEN OPEN * Load and open a session to a Trustlet. * The OPEN command loads Trustlet data to the MobiCore context and opens a * session to the Trustlet. If wsm_data_type is WSM_INVALID MobiCore tries to * start a pre-installed Trustlet associated with the uuid passed. The uuid * passed must match the uuid contained in the load data (if available). * On success, MobiCore returns the session ID which can be used for further * communication. */ /** GP client authentication data */ struct cmd_open_data { uint32_t mclf_magic; /** ASCII "MCLF" on older versions */ struct identity identity; /** Login method and data */ }; /** Open Command */ struct cmd_open { struct cmd_header cmd_header; /** Command header */ struct mc_uuid_t uuid; /** Service UUID */ uint8_t unused[4]; /** Padding to be 64-bit aligned */ uint64_t adr_tci_buffer; /** Physical address of the TCI MMU */ uint64_t adr_load_data; /** Physical address of the data MMU */ uint32_t ofs_tci_buffer; /** Offset to the data */ uint32_t len_tci_buffer; /** Length of the TCI */ uint32_t wsmtype_tci; /** Type of WSM used for the TCI */ uint32_t wsm_data_type; /** Type of MMU */ uint32_t ofs_load_data; /** Offset to the data */ uint32_t len_load_data; /** Length of the data to load */ union { struct cmd_open_data cmd_open_data; /** Client login data */ union mclf_header tl_header; /** Service header */ }; uint32_t is_gpta; /** true if looking for an SD/GP-TA */ }; /** Open Command Response */ struct rsp_open { struct rsp_header rsp_header; /** Response header */ uint32_t session_id; /** Session ID */ }; /** TA Load Check Command */ struct cmd_check_load { struct cmd_header cmd_header; /** Command header */ struct mc_uuid_t uuid; /** Service UUID */ uint64_t adr_load_data; /** Physical address of the data */ uint32_t wsm_data_type; /** Type of MMU */ uint32_t ofs_load_data; /** Offset to the data */ uint32_t len_load_data; /** Length of the data to load */ union mclf_header tl_header; /** Service header */ }; /** TA Load Check Response */ struct rsp_check_load { struct rsp_header rsp_header; /** Response header */ }; /** @defgroup MCPCLOSE CLOSE * Close an existing session to a Trustlet. * The CLOSE command terminates a session and frees all resources in the * MobiCore system which are currently occupied by the session. Before closing * the session, the MobiCore runtime management waits until all pending * operations, like calls to drivers, invoked by the Trustlet have been * terminated. Mapped memory will automatically be unmapped from the MobiCore * context. The NWd is responsible for processing the freed memory according to * the Rich-OS needs. * */ /** Close Command */ struct cmd_close { struct cmd_header cmd_header; /** Command header */ uint32_t session_id; /** Session ID */ }; /** Close Command Response */ struct rsp_close { struct rsp_header rsp_header; /** Response header */ }; /** @defgroup MCPMAP MAP * Map a portion of memory to a session. * The MAP command provides a block of memory to the context of a service. * The memory then becomes world-shared memory (WSM). * The only allowed memory type here is WSM_L2. */ /** Map Command */ struct cmd_map { struct cmd_header cmd_header; /** Command header */ uint32_t session_id; /** Session ID */ uint32_t wsm_type; /** Type of MMU */ uint32_t ofs_buffer; /** Offset to the payload */ uint64_t adr_buffer; /** Physical address of the MMU */ uint32_t len_buffer; /** Length of the buffer */ }; #define MCP_MAP_MAX 0x100000 /** Maximum length for MCP map */ /** Map Command Response */ struct rsp_map { struct rsp_header rsp_header; /** Response header */ /** Virtual address the WSM is mapped to, may include an offset! */ uint32_t secure_va; }; /** @defgroup MCPUNMAP UNMAP * Unmap a portion of world-shared memory from a session. * The UNMAP command is used to unmap a previously mapped block of * world shared memory from the context of a session. * * Attention: The memory block will be immediately unmapped from the specified * session. If the service is still accessing the memory, the service will * trigger a segmentation fault. */ /** Unmap Command */ struct cmd_unmap { struct cmd_header cmd_header; /** Command header */ uint32_t session_id; /** Session ID */ uint32_t wsm_type; /** Type of WSM used of the memory */ /** Virtual address the WSM is mapped to, may include an offset! */ uint32_t secure_va; uint32_t virtual_buffer_len; /** Length of virtual buffer */ }; /** Unmap Command Response */ struct rsp_unmap { struct rsp_header rsp_header; /** Response header */ }; /** @defgroup MCPLOADTOKEN * Load a token from the normal world and share it with