1 /* 2 * QEMU TPM Backend 3 * 4 * Copyright IBM, Corp. 2013 5 * 6 * Authors: 7 * Stefan Berger <stefanb@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #ifndef TPM_BACKEND_H 14 #define TPM_BACKEND_H 15 16 #include "qom/object.h" 17 #include "qemu-common.h" 18 #include "qapi-types.h" 19 #include "qemu/option.h" 20 #include "sysemu/tpm.h" 21 22 #define TYPE_TPM_BACKEND "tpm-backend" 23 #define TPM_BACKEND(obj) \ 24 OBJECT_CHECK(TPMBackend, (obj), TYPE_TPM_BACKEND) 25 #define TPM_BACKEND_GET_CLASS(obj) \ 26 OBJECT_GET_CLASS(TPMBackendClass, (obj), TYPE_TPM_BACKEND) 27 #define TPM_BACKEND_CLASS(klass) \ 28 OBJECT_CLASS_CHECK(TPMBackendClass, (klass), TYPE_TPM_BACKEND) 29 30 typedef struct TPMBackendClass TPMBackendClass; 31 typedef struct TPMBackend TPMBackend; 32 typedef struct TPMDriverOps TPMDriverOps; 33 typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty, bool selftest_done); 34 35 typedef enum TPMBackendCmd { 36 TPM_BACKEND_CMD_INIT = 1, 37 TPM_BACKEND_CMD_PROCESS_CMD, 38 TPM_BACKEND_CMD_END, 39 TPM_BACKEND_CMD_TPM_RESET, 40 } TPMBackendCmd; 41 42 struct TPMBackend { 43 Object parent; 44 45 /*< protected >*/ 46 bool opened; 47 TPMState *tpm_state; 48 GThreadPool *thread_pool; 49 TPMRecvDataCB *recv_data_callback; 50 bool had_startup_error; 51 52 /* <public> */ 53 char *id; 54 enum TpmModel fe_model; 55 56 QLIST_ENTRY(TPMBackend) list; 57 }; 58 59 struct TPMBackendClass { 60 ObjectClass parent_class; 61 62 const TPMDriverOps *ops; 63 64 void (*opened)(TPMBackend *s, Error **errp); 65 66 void (*handle_request)(TPMBackend *s, TPMBackendCmd cmd); 67 }; 68 69 typedef struct TPMSizedBuffer { 70 uint32_t size; 71 uint8_t *buffer; 72 } TPMSizedBuffer; 73 74 struct TPMDriverOps { 75 enum TpmType type; 76 const QemuOptDesc *opts; 77 /* get a descriptive text of the backend to display to the user */ 78 const char *desc; 79 80 TPMBackend *(*create)(QemuOpts *opts, const char *id); 81 82 /* initialize the backend */ 83 int (*init)(TPMBackend *t); 84 /* start up the TPM on the backend */ 85 int (*startup_tpm)(TPMBackend *t); 86 87 void (*reset)(TPMBackend *t); 88 89 void (*cancel_cmd)(TPMBackend *t); 90 91 bool (*get_tpm_established_flag)(TPMBackend *t); 92 93 int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty); 94 95 TPMVersion (*get_tpm_version)(TPMBackend *t); 96 97 TpmTypeOptions *(*get_tpm_options)(TPMBackend *t); 98 }; 99 100 101 /** 102 * tpm_backend_get_type: 103 * @s: the backend 104 * 105 * Returns the TpmType of the backend. 106 */ 107 enum TpmType tpm_backend_get_type(TPMBackend *s); 108 109 /** 110 * tpm_backend_init: 111 * @s: the backend to initialized 112 * @state: TPMState 113 * @datacb: callback for sending data to frontend 114 * 115 * Initialize the backend with the given variables. 116 * 117 * Returns 0 on success. 118 */ 119 int tpm_backend_init(TPMBackend *s, TPMState *state, 120 TPMRecvDataCB *datacb); 121 122 /** 123 * tpm_backend_startup_tpm: 124 * @s: the backend whose TPM support is to be started 125 * 126 * Returns 0 on success. 127 */ 128 int tpm_backend_startup_tpm(TPMBackend *s); 129 130 /** 131 * tpm_backend_had_startup_error: 132 * @s: the backend to query for a statup error 133 * 134 * Check whether the backend had an error during startup. Returns 135 * false if no error occurred and the backend can be used, true 136 * otherwise. 137 */ 138 bool tpm_backend_had_startup_error(TPMBackend *s); 139 140 /** 141 * tpm_backend_deliver_request: 142 * @s: the backend to send the request to 143 * 144 * Send a request to the backend. The backend will then send the request 145 * to the TPM implementation. 146 */ 147 void tpm_backend_deliver_request(TPMBackend *s); 148 149 /** 150 * tpm_backend_reset: 151 * @s: the backend to reset 152 * 153 * Reset the backend into a well defined state with all previous errors 154 * reset. 155 */ 156 void tpm_backend_reset(TPMBackend *s); 157 158 /** 159 * tpm_backend_cancel_cmd: 160 * @s: the backend 161 * 162 * Cancel any ongoing command being processed by the TPM implementation 163 * on behalf of the QEMU guest. 164 */ 165 void tpm_backend_cancel_cmd(TPMBackend *s); 166 167 /** 168 * tpm_backend_get_tpm_established_flag: 169 * @s: the backend 170 * 171 * Get the TPM establishment flag. This function may be called very 172 * frequently by the frontend since for example in the TIS implementation 173 * this flag is part of a register. 174 */ 175 bool tpm_backend_get_tpm_established_flag(TPMBackend *s); 176 177 /** 178 * tpm_backend_reset_tpm_established_flag: 179 * @s: the backend 180 * @locty: the locality number 181 * 182 * Reset the TPM establishment flag. 183 */ 184 int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty); 185 186 /** 187 * tpm_backend_open: 188 * @s: the backend to open 189 * @errp: a pointer to return the #Error object if an error occurs. 190 * 191 * This function will open the backend if it is not already open. Calling this 192 * function on an already opened backend will not result in an error. 193 */ 194 void tpm_backend_open(TPMBackend *s, Error **errp); 195 196 /** 197 * tpm_backend_get_tpm_version: 198 * @s: the backend to call into 199 * 200 * Get the TPM Version that is emulated at the backend. 201 * 202 * Returns TPMVersion. 203 */ 204 TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); 205 206 /** 207 * tpm_backend_query_tpm: 208 * @s: the backend 209 * 210 * Query backend tpm info 211 * 212 * Returns newly allocated TPMInfo 213 */ 214 TPMInfo *tpm_backend_query_tpm(TPMBackend *s); 215 216 TPMBackend *qemu_find_tpm(const char *id); 217 218 const TPMDriverOps *tpm_get_backend_driver(const char *type); 219 void tpm_register_model(enum TpmModel model); 220 void tpm_register_driver(const TPMDriverOps *tdo); 221 222 #endif 223