18f0605ccSStefan Berger /* 28f0605ccSStefan Berger * QEMU TPM Backend 38f0605ccSStefan Berger * 48f0605ccSStefan Berger * Copyright IBM, Corp. 2013 58f0605ccSStefan Berger * 68f0605ccSStefan Berger * Authors: 78f0605ccSStefan Berger * Stefan Berger <stefanb@us.ibm.com> 88f0605ccSStefan Berger * 98f0605ccSStefan Berger * This work is licensed under the terms of the GNU GPL, version 2 or later. 108f0605ccSStefan Berger * See the COPYING file in the top-level directory. 118f0605ccSStefan Berger */ 128f0605ccSStefan Berger 13121d0712SMarkus Armbruster #ifndef TPM_BACKEND_H 14121d0712SMarkus Armbruster #define TPM_BACKEND_H 158f0605ccSStefan Berger 168f0605ccSStefan Berger #include "qom/object.h" 178f0605ccSStefan Berger #include "qemu/option.h" 18*32cad1ffSPhilippe Mathieu-Daudé #include "system/tpm.h" 196a8a2354SMarc-André Lureau #include "qapi/error.h" 208f0605ccSStefan Berger 21e542b718SStefan Berger #ifdef CONFIG_TPM 22e542b718SStefan Berger 238f0605ccSStefan Berger #define TYPE_TPM_BACKEND "tpm-backend" 24c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(TPMBackend, TPMBackendClass, 2530b5707cSEduardo Habkost TPM_BACKEND) 268f0605ccSStefan Berger 27d31076baSMarc-André Lureau 280e43b7e6SMarc-André Lureau typedef struct TPMBackendCmd { 290e43b7e6SMarc-André Lureau uint8_t locty; 300e43b7e6SMarc-André Lureau const uint8_t *in; 310e43b7e6SMarc-André Lureau uint32_t in_len; 320e43b7e6SMarc-André Lureau uint8_t *out; 330e43b7e6SMarc-André Lureau uint32_t out_len; 340e43b7e6SMarc-André Lureau bool selftest_done; 350e43b7e6SMarc-André Lureau } TPMBackendCmd; 368f0605ccSStefan Berger 378f0605ccSStefan Berger struct TPMBackend { 388f0605ccSStefan Berger Object parent; 398f0605ccSStefan Berger 408f0605ccSStefan Berger /*< protected >*/ 418a89c9acSMarc-André Lureau TPMIf *tpmif; 428f0605ccSStefan Berger bool opened; 4393330cf5SAmarnath Valluri bool had_startup_error; 44c4fb8561SMarc-André Lureau TPMBackendCmd *cmd; 458f0605ccSStefan Berger 46f59864baSAmarnath Valluri /* <public> */ 478f0605ccSStefan Berger char *id; 488f0605ccSStefan Berger 498f0605ccSStefan Berger QLIST_ENTRY(TPMBackend) list; 508f0605ccSStefan Berger }; 518f0605ccSStefan Berger 52b19a5eeaSAmarnath Valluri struct TPMBackendClass { 53b19a5eeaSAmarnath Valluri ObjectClass parent_class; 54b19a5eeaSAmarnath Valluri 55bdee56f5SPaolo Bonzini enum TpmType type; 56bb716238SStefan Berger const QemuOptDesc *opts; 57bdee56f5SPaolo Bonzini /* get a descriptive text of the backend to display to the user */ 5893330cf5SAmarnath Valluri const char *desc; 59bdee56f5SPaolo Bonzini 609f7c0ef2SMarc-André Lureau TPMBackend *(*create)(QemuOpts *opts); 61bdee56f5SPaolo Bonzini 62ebca2df7SMarc-André Lureau /* start up the TPM on the backend - optional */ 639375c44fSStefan Berger int (*startup_tpm)(TPMBackend *t, size_t buffersize); 64bdee56f5SPaolo Bonzini 65ebca2df7SMarc-André Lureau /* optional */ 66bdee56f5SPaolo Bonzini void (*reset)(TPMBackend *t); 67bdee56f5SPaolo Bonzini 68bdee56f5SPaolo Bonzini void (*cancel_cmd)(TPMBackend *t); 69bdee56f5SPaolo Bonzini 70ebca2df7SMarc-André Lureau /* optional */ 71bdee56f5SPaolo Bonzini bool (*get_tpm_established_flag)(TPMBackend *t); 72116694c3SStefan Berger 73ebca2df7SMarc-André Lureau /* optional */ 74116694c3SStefan Berger int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty); 75116694c3SStefan Berger 76116694c3SStefan Berger TPMVersion (*get_tpm_version)(TPMBackend *t); 77f59864baSAmarnath Valluri 78b21e6aafSStefan Berger size_t (*get_buffer_size)(TPMBackend *t); 79b21e6aafSStefan Berger 80f59864baSAmarnath Valluri TpmTypeOptions *(*get_tpm_options)(TPMBackend *t); 81bdee56f5SPaolo Bonzini 826a8a2354SMarc-André Lureau void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd, Error **errp); 83d31076baSMarc-André Lureau }; 848f0605ccSStefan Berger 858f0605ccSStefan Berger /** 868f0605ccSStefan Berger * tpm_backend_get_type: 878f0605ccSStefan Berger * @s: the backend 888f0605ccSStefan Berger * 898f0605ccSStefan Berger * Returns the TpmType of the backend. 908f0605ccSStefan Berger */ 918f0605ccSStefan Berger enum TpmType tpm_backend_get_type(TPMBackend *s); 928f0605ccSStefan Berger 938f0605ccSStefan Berger /** 948f0605ccSStefan Berger * tpm_backend_init: 958f0605ccSStefan Berger * @s: the backend to initialized 968a89c9acSMarc-André Lureau * @tpmif: TPM interface 978f0605ccSStefan Berger * @datacb: callback for sending data to frontend 980bd6c8a9SMarc-André Lureau * @errp: a pointer to return the #Error object if an error occurs. 998f0605ccSStefan Berger * 1008f0605ccSStefan Berger * Initialize the backend with the given variables. 1018f0605ccSStefan Berger * 1028f0605ccSStefan Berger * Returns 0 on success. 1038f0605ccSStefan Berger */ 1040bd6c8a9SMarc-André Lureau int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp); 1058f0605ccSStefan Berger 1068f0605ccSStefan Berger /** 1078f0605ccSStefan Berger * tpm_backend_startup_tpm: 1088f0605ccSStefan Berger * @s: the backend whose TPM support is to be started 1099375c44fSStefan Berger * @buffersize: the buffer size the TPM is supposed to use, 1109375c44fSStefan Berger * 0 to leave it as-is 1118f0605ccSStefan Berger * 1128f0605ccSStefan Berger * Returns 0 on success. 1138f0605ccSStefan Berger */ 1149375c44fSStefan Berger int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize); 1158f0605ccSStefan Berger 1168f0605ccSStefan Berger /** 1178f0605ccSStefan Berger * tpm_backend_had_startup_error: 118a1a62cedSMichael Tokarev * @s: the backend to query for a startup error 1198f0605ccSStefan Berger * 1208f0605ccSStefan Berger * Check whether the backend had an error during startup. Returns 1218f0605ccSStefan Berger * false if no error occurred and the backend can be used, true 1228f0605ccSStefan Berger * otherwise. 1238f0605ccSStefan Berger */ 1248f0605ccSStefan Berger bool tpm_backend_had_startup_error(TPMBackend *s); 1258f0605ccSStefan Berger 1268f0605ccSStefan Berger /** 1278f0605ccSStefan Berger * tpm_backend_deliver_request: 1288f0605ccSStefan Berger * @s: the backend to send the request to 1290e43b7e6SMarc-André Lureau * @cmd: the command to deliver 1308f0605ccSStefan Berger * 1318f0605ccSStefan Berger * Send a request to the backend. The backend will then send the request 1328f0605ccSStefan Berger * to the TPM implementation. 1338f0605ccSStefan Berger */ 1340e43b7e6SMarc-André Lureau void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd); 1358f0605ccSStefan Berger 1368f0605ccSStefan Berger /** 1378f0605ccSStefan Berger * tpm_backend_reset: 1388f0605ccSStefan Berger * @s: the backend to reset 1398f0605ccSStefan Berger * 1408f0605ccSStefan Berger * Reset the backend into a well defined state with all previous errors 1418f0605ccSStefan Berger * reset. 1428f0605ccSStefan Berger */ 1438f0605ccSStefan Berger void tpm_backend_reset(TPMBackend *s); 1448f0605ccSStefan Berger 1458f0605ccSStefan Berger /** 1468f0605ccSStefan Berger * tpm_backend_cancel_cmd: 1478f0605ccSStefan Berger * @s: the backend 1488f0605ccSStefan Berger * 1498f0605ccSStefan Berger * Cancel any ongoing command being processed by the TPM implementation 1508f0605ccSStefan Berger * on behalf of the QEMU guest. 1518f0605ccSStefan Berger */ 1528f0605ccSStefan Berger void tpm_backend_cancel_cmd(TPMBackend *s); 1538f0605ccSStefan Berger 1548f0605ccSStefan Berger /** 1558f0605ccSStefan Berger * tpm_backend_get_tpm_established_flag: 1568f0605ccSStefan Berger * @s: the backend 1578f0605ccSStefan Berger * 1588f0605ccSStefan Berger * Get the TPM establishment flag. This function may be called very 1598f0605ccSStefan Berger * frequently by the frontend since for example in the TIS implementation 1608f0605ccSStefan Berger * this flag is part of a register. 1618f0605ccSStefan Berger */ 1628f0605ccSStefan Berger bool tpm_backend_get_tpm_established_flag(TPMBackend *s); 1638f0605ccSStefan Berger 1648f0605ccSStefan Berger /** 165116694c3SStefan Berger * tpm_backend_reset_tpm_established_flag: 166116694c3SStefan Berger * @s: the backend 167116694c3SStefan Berger * @locty: the locality number 168116694c3SStefan Berger * 169116694c3SStefan Berger * Reset the TPM establishment flag. 170116694c3SStefan Berger */ 171116694c3SStefan Berger int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty); 172116694c3SStefan Berger 173116694c3SStefan Berger /** 174116694c3SStefan Berger * tpm_backend_get_tpm_version: 175116694c3SStefan Berger * @s: the backend to call into 176116694c3SStefan Berger * 177116694c3SStefan Berger * Get the TPM Version that is emulated at the backend. 178116694c3SStefan Berger * 179116694c3SStefan Berger * Returns TPMVersion. 180116694c3SStefan Berger */ 181116694c3SStefan Berger TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); 182116694c3SStefan Berger 183f59864baSAmarnath Valluri /** 184b21e6aafSStefan Berger * tpm_backend_get_buffer_size: 185b21e6aafSStefan Berger * @s: the backend to call into 186b21e6aafSStefan Berger * 187b21e6aafSStefan Berger * Get the TPM's buffer size. 188b21e6aafSStefan Berger * 189b21e6aafSStefan Berger * Returns buffer size. 190b21e6aafSStefan Berger */ 191b21e6aafSStefan Berger size_t tpm_backend_get_buffer_size(TPMBackend *s); 192b21e6aafSStefan Berger 193b21e6aafSStefan Berger /** 194c4fb8561SMarc-André Lureau * tpm_backend_finish_sync: 195c4fb8561SMarc-André Lureau * @s: the backend to call into 196c4fb8561SMarc-André Lureau * 197c4fb8561SMarc-André Lureau * Finish the pending command synchronously (this will call aio_poll() 198c4fb8561SMarc-André Lureau * on qemu main AIOContext until it ends) 199c4fb8561SMarc-André Lureau */ 200c4fb8561SMarc-André Lureau void tpm_backend_finish_sync(TPMBackend *s); 201c4fb8561SMarc-André Lureau 202c4fb8561SMarc-André Lureau /** 203f59864baSAmarnath Valluri * tpm_backend_query_tpm: 204f59864baSAmarnath Valluri * @s: the backend 205f59864baSAmarnath Valluri * 206f59864baSAmarnath Valluri * Query backend tpm info 207f59864baSAmarnath Valluri * 208f59864baSAmarnath Valluri * Returns newly allocated TPMInfo 209f59864baSAmarnath Valluri */ 210f59864baSAmarnath Valluri TPMInfo *tpm_backend_query_tpm(TPMBackend *s); 211f59864baSAmarnath Valluri 212d36e7db1SMarc-André Lureau TPMBackend *qemu_find_tpm_be(const char *id); 213bdee56f5SPaolo Bonzini 214e542b718SStefan Berger #endif /* CONFIG_TPM */ 215e542b718SStefan Berger 216e542b718SStefan Berger #endif /* TPM_BACKEND_H */ 217