From nobody Sun Apr 28 23:45:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1524156109230652.336307067061; Thu, 19 Apr 2018 09:41:49 -0700 (PDT) Received: from localhost ([::1]:60201 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f9Cd2-000878-Bz for importer@patchew.org; Thu, 19 Apr 2018 12:41:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56681) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f9CbM-0006u6-DL for qemu-devel@nongnu.org; Thu, 19 Apr 2018 12:40:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f9CbI-0000GI-BK for qemu-devel@nongnu.org; Thu, 19 Apr 2018 12:40:04 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:45544) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f9CbI-0000Ds-2F for qemu-devel@nongnu.org; Thu, 19 Apr 2018 12:40:00 -0400 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w3JGbrXj066222 for ; Thu, 19 Apr 2018 12:39:58 -0400 Received: from e31.co.us.ibm.com (e31.co.us.ibm.com [32.97.110.149]) by mx0a-001b2d01.pphosted.com with ESMTP id 2hevpyxu2p-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Thu, 19 Apr 2018 12:39:57 -0400 Received: from localhost by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 19 Apr 2018 10:39:57 -0600 Received: from b03cxnp08025.gho.boulder.ibm.com (9.17.130.17) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 19 Apr 2018 10:39:54 -0600 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w3JGdsLo12190128; Thu, 19 Apr 2018 09:39:54 -0700 Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3E0ECBE038; Thu, 19 Apr 2018 10:39:54 -0600 (MDT) Received: from sbct-3.watson.ibm.com (unknown [9.47.158.153]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP id CE506BE039; Thu, 19 Apr 2018 10:39:53 -0600 (MDT) From: Stefan Berger To: marcandre.lureau@gmail.com, qemu-devel@nongnu.org Date: Thu, 19 Apr 2018 12:39:43 -0400 X-Mailer: git-send-email 2.5.5 MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 18041916-8235-0000-0000-00000D56A741 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008883; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000257; SDB=6.01020251; UDB=6.00520560; IPR=6.00799488; MB=3.00020667; MTD=3.00000008; XFM=3.00000015; UTC=2018-04-19 16:39:55 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18041916-8236-0000-0000-0000408E33A8 Message-Id: <1524155983-16705-1-git-send-email-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-04-19_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1804190144 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0a-001b2d01.pphosted.com id w3JGbrXj066222 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH] test: Add test cases that use the external swtpm with CRB interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com, Stefan Berger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add a test program for testing the CRB with the external swtpm. The 1st test case extends a PCR and reads back the value and compares it against an expected return packet. The 2nd test case repeats the 1st test case and then migrates the external swtpm's state along with the VM state to a destination QEMU and swtpm and checks that the PCR has the expected value now. Signed-off-by: Stefan Berger Reviewed-by: Marc-Andr=C3=A9 Lureau --- tests/Makefile.include | 3 + tests/tpm-crb-swtpm-test.c | 247 +++++++++++++++++++++++++++++++++++++++++= ++++ tests/tpm-util.c | 186 ++++++++++++++++++++++++++++++++++ tests/tpm-util.h | 36 +++++++ 4 files changed, 472 insertions(+) create mode 100644 tests/tpm-crb-swtpm-test.c create mode 100644 tests/tpm-util.c create mode 100644 tests/tpm-util.h diff --git a/tests/Makefile.include b/tests/Makefile.include index 3b9a5e3..b499ba1 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -297,6 +297,7 @@ check-qtest-i386-$(CONFIG_VHOST_USER_NET_TEST_i386) += =3D tests/vhost-user-test$(EX ifeq ($(CONFIG_VHOST_USER_NET_TEST_i386),) check-qtest-x86_64-$(CONFIG_VHOST_USER_NET_TEST_x86_64) +=3D tests/vhost-u= ser-test$(EXESUF) endif +check-qtest-i386-$(CONFIG_TPM) +=3D tests/tpm-crb-swtpm-test$(EXESUF) check-qtest-i386-$(CONFIG_TPM) +=3D tests/tpm-crb-test$(EXESUF) check-qtest-i386-$(CONFIG_TPM) +=3D tests/tpm-tis-test$(EXESUF) check-qtest-i386-$(CONFIG_SLIRP) +=3D tests/test-netfilter$(EXESUF) @@ -721,6 +722,8 @@ tests/test-util-sockets$(EXESUF): tests/test-util-socke= ts.o \ tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y) tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \ tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y) +tests/tpm-crb-swtpm-test$(EXESUF): tests/tpm-crb-swtpm-test.o tests/tpm-em= u.o \ + tests/tpm-util.o $(test-io-obj-y) tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o $(test-i= o-obj-y) tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o $(test-i= o-obj-y) tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \ diff --git a/tests/tpm-crb-swtpm-test.c b/tests/tpm-crb-swtpm-test.c new file mode 100644 index 0000000..505a927 --- /dev/null +++ b/tests/tpm-crb-swtpm-test.c @@ -0,0 +1,247 @@ +/* + * QTest testcase for TPM CRB talking to external swtpm and swtpm migration + * + * Copyright (c) 2018 IBM Corporation + * with parts borrowed from migration-test.c that is: + * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates + * + * Authors: + * Stefan Berger + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include + +#include "hw/acpi/tpm.h" +#include "io/channel-socket.h" +#include "libqtest.h" +#include "tpm-util.h" +#include "sysemu/tpm.h" +#include "qapi/qmp/qdict.h" + +typedef struct TestState { + char *src_tpm_path; + char *dst_tpm_path; + char *uri; +} TestState; + +bool got_stop; + +static void migrate(QTestState *who, const char *uri) +{ + QDict *rsp; + gchar *cmd; + + cmd =3D g_strdup_printf("{ 'execute': 'migrate'," + "'arguments': { 'uri': '%s' } }", + uri); + rsp =3D qtest_qmp(who, cmd); + g_free(cmd); + g_assert(qdict_haskey(rsp, "return")); + QDECREF(rsp); +} + +/* + * Events can get in the way of responses we are actually waiting for. + */ +static QDict *wait_command(QTestState *who, const char *command) +{ + const char *event_string; + QDict *response; + + response =3D qtest_qmp(who, command); + + while (qdict_haskey(response, "event")) { + /* OK, it was an event */ + event_string =3D qdict_get_str(response, "event"); + if (!strcmp(event_string, "STOP")) { + got_stop =3D true; + } + QDECREF(response); + response =3D qtest_qmp_receive(who); + } + return response; +} + +static void wait_for_migration_complete(QTestState *who) +{ + while (true) { + QDict *rsp, *rsp_return; + bool completed; + const char *status; + + rsp =3D wait_command(who, "{ 'execute': 'query-migrate' }"); + rsp_return =3D qdict_get_qdict(rsp, "return"); + status =3D qdict_get_str(rsp_return, "status"); + completed =3D strcmp(status, "completed") =3D=3D 0; + g_assert_cmpstr(status, !=3D, "failed"); + QDECREF(rsp); + if (completed) { + return; + } + usleep(1000); + } +} + +static void migration_start_qemu(QTestState **src_qemu, QTestState **dst_q= emu, + SocketAddress *src_tpm_addr, + SocketAddress *dst_tpm_addr, + const char *miguri) +{ + char *src_qemu_args, *dst_qemu_args; + + src_qemu_args =3D g_strdup_printf( + "-chardev socket,id=3Dchr,path=3D%s " + "-tpmdev emulator,id=3Ddev,chardev=3Dchr " + "-device tpm-crb,tpmdev=3Ddev ", + src_tpm_addr->u.q_unix.path); + + *src_qemu =3D qtest_init(src_qemu_args); + + dst_qemu_args =3D g_strdup_printf( + "-chardev socket,id=3Dchr,path=3D%s " + "-tpmdev emulator,id=3Ddev,chardev=3Dchr " + "-device tpm-crb,tpmdev=3Ddev " + "-incoming %s", + dst_tpm_addr->u.q_unix.path, + miguri); + + *dst_qemu =3D qtest_init(dst_qemu_args); + + free(src_qemu_args); + free(dst_qemu_args); +} + +static void tpm_crb_swtpm_test(const void *data) +{ + char *args =3D NULL; + QTestState *s; + SocketAddress *addr =3D NULL; + gboolean succ; + GPid swtpm_pid; + GError *error =3D NULL; + const TestState *ts =3D data; + + succ =3D tpm_util_swtpm_start(ts->src_tpm_path, &swtpm_pid, &addr, &er= ror); + /* succ may be false if swtpm is not available */ + if (!succ) { + return; + } + + args =3D g_strdup_printf( + "-chardev socket,id=3Dchr,path=3D%s " + "-tpmdev emulator,id=3Ddev,chardev=3Dchr " + "-device tpm-crb,tpmdev=3Ddev", + addr->u.q_unix.path); + + s =3D qtest_start(args); + g_free(args); + + tpm_util_startup(s, tpm_util_crb_transfer); + tpm_util_pcrextend(s, tpm_util_crb_transfer); + + unsigned char tpm_pcrread_resp[] =3D + "\x80\x01\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00" + "\x00\x01\x00\x0b\x03\x00\x04\x00\x00\x00\x00\x01\x00\x20\xf6\x85" + "\x98\xe5\x86\x8d\xe6\x8b\x97\x29\x99\x60\xf2\x71\x7d\x17\x67\x89" + "\xa4\x2f\x9a\xae\xa8\xc7\xb7\xaa\x79\xa8\x62\x56\xc1\xde"; + tpm_util_pcrread(s, tpm_util_crb_transfer, tpm_pcrread_resp, + sizeof(tpm_pcrread_resp)); + + qtest_end(); + tpm_util_swtpm_kill(swtpm_pid); + + if (addr) { + g_unlink(addr->u.q_unix.path); + qapi_free_SocketAddress(addr); + } +} + +static void tpm_crb_swtpm_migration_test(const void *data) +{ + const TestState *ts =3D data; + gboolean succ; + GPid src_tpm_pid, dst_tpm_pid; + SocketAddress *src_tpm_addr =3D NULL, *dst_tpm_addr =3D NULL; + GError *error =3D NULL; + QTestState *src_qemu, *dst_qemu; + + succ =3D tpm_util_swtpm_start(ts->src_tpm_path, &src_tpm_pid, + &src_tpm_addr, &error); + /* succ may be false if swtpm is not available */ + if (!succ) { + return; + } + + succ =3D tpm_util_swtpm_start(ts->dst_tpm_path, &dst_tpm_pid, + &dst_tpm_addr, &error); + /* succ may be false if swtpm is not available */ + if (!succ) { + goto err_src_tpm_kill; + } + + migration_start_qemu(&src_qemu, &dst_qemu, src_tpm_addr, dst_tpm_addr, + ts->uri); + + tpm_util_startup(src_qemu, tpm_util_crb_transfer); + tpm_util_pcrextend(src_qemu, tpm_util_crb_transfer); + + unsigned char tpm_pcrread_resp[] =3D + "\x80\x01\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00" + "\x00\x01\x00\x0b\x03\x00\x04\x00\x00\x00\x00\x01\x00\x20\xf6\x85" + "\x98\xe5\x86\x8d\xe6\x8b\x97\x29\x99\x60\xf2\x71\x7d\x17\x67\x89" + "\xa4\x2f\x9a\xae\xa8\xc7\xb7\xaa\x79\xa8\x62\x56\xc1\xde"; + tpm_util_pcrread(src_qemu, tpm_util_crb_transfer, tpm_pcrread_resp, + sizeof(tpm_pcrread_resp)); + + migrate(src_qemu, ts->uri); + wait_for_migration_complete(src_qemu); + + tpm_util_pcrread(dst_qemu, tpm_util_crb_transfer, tpm_pcrread_resp, + sizeof(tpm_pcrread_resp)); + + qtest_quit(dst_qemu); + qtest_quit(src_qemu); + + tpm_util_swtpm_kill(dst_tpm_pid); + if (dst_tpm_addr) { + g_unlink(dst_tpm_addr->u.q_unix.path); + qapi_free_SocketAddress(dst_tpm_addr); + } + +err_src_tpm_kill: + tpm_util_swtpm_kill(src_tpm_pid); + if (src_tpm_addr) { + g_unlink(src_tpm_addr->u.q_unix.path); + qapi_free_SocketAddress(src_tpm_addr); + } +} + +int main(int argc, char **argv) +{ + int ret; + TestState ts =3D { 0 }; + + ts.src_tpm_path =3D g_dir_make_tmp("qemu-tpm-crb-swtpm-test.XXXXXX", N= ULL); + ts.dst_tpm_path =3D g_dir_make_tmp("qemu-tpm-crb-swtpm-test.XXXXXX", N= ULL); + ts.uri =3D g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path); + + module_call_init(MODULE_INIT_QOM); + g_test_init(&argc, &argv, NULL); + + qtest_add_data_func("/tpm/crb-swtpm/test", &ts, tpm_crb_swtpm_test); + qtest_add_data_func("/tpm/crb-swtpm-migration/test", &ts, + tpm_crb_swtpm_migration_test); + ret =3D g_test_run(); + + g_rmdir(ts.dst_tpm_path); + g_free(ts.dst_tpm_path); + g_rmdir(ts.src_tpm_path); + g_free(ts.src_tpm_path); + g_free(ts.uri); + + return ret; +} diff --git a/tests/tpm-util.c b/tests/tpm-util.c new file mode 100644 index 0000000..9072b6e --- /dev/null +++ b/tests/tpm-util.c @@ -0,0 +1,186 @@ +/* + * QTest TPM utilities + * + * Copyright (c) 2018 IBM Corporation + * Copyright (c) 2018 Red Hat, Inc. + * + * Authors: + * Stefan Berger + * Marc-Andr=C3=A9 Lureau + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "hw/acpi/tpm.h" +#include "libqtest.h" +#include "tpm-util.h" + +void tpm_util_crb_transfer(QTestState *s, + const unsigned char *req, size_t req_size, + unsigned char *rsp, size_t rsp_size) +{ + uint64_t caddr =3D qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_L= ADDR); + uint64_t raddr =3D qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_A= DDR); + + qtest_writeb(s, TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL, 1); + + qtest_memwrite(s, caddr, req, req_size); + + uint32_t sts, start =3D 1; + uint64_t end_time =3D g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; + qtest_writel(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START, start); + while (true) { + start =3D qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START); + if ((start & 1) =3D=3D 0) { + break; + } + if (g_get_monotonic_time() >=3D end_time) { + break; + } + }; + start =3D qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START); + g_assert_cmpint(start & 1, =3D=3D, 0); + sts =3D qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS); + g_assert_cmpint(sts & 1, =3D=3D, 0); + + qtest_memread(s, raddr, rsp, rsp_size); +} + +void tpm_util_startup(QTestState *s, tx_func *tx) +{ + unsigned char buffer[1024]; + unsigned char tpm_startup[] =3D + "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"; + unsigned char tpm_startup_resp[] =3D + "\x80\x01\x00\x00\x00\x0a\x00\x00\x00\x00"; + + tx(s, tpm_startup, sizeof(tpm_startup), buffer, sizeof(buffer)); + + g_assert_cmpmem(buffer, sizeof(tpm_startup_resp), + tpm_startup_resp, sizeof(tpm_startup_resp)); +} + +void tpm_util_pcrextend(QTestState *s, tx_func *tx) +{ + unsigned char buffer[1024]; + unsigned char tpm_pcrextend[] =3D + "\x80\x02\x00\x00\x00\x41\x00\x00\x01\x82\x00\x00\x00\x0a\x00\x00" + "\x00\x09\x40\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x0b\x74\x65\x73\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00"; + + unsigned char tpm_pcrextend_resp[] =3D + "\x80\x02\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00"; + + tx(s, tpm_pcrextend, sizeof(tpm_pcrextend), buffer, sizeof(buffer)); + + g_assert_cmpmem(buffer, sizeof(tpm_pcrextend_resp), + tpm_pcrextend_resp, sizeof(tpm_pcrextend_resp)); +} + +void tpm_util_pcrread(QTestState *s, tx_func *tx, + const unsigned char *exp_resp, size_t exp_resp_size) +{ + unsigned char buffer[1024]; + unsigned char tpm_pcrread[] =3D + "\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b" + "\x03\x00\x04\x00"; + + tx(s, tpm_pcrread, sizeof(tpm_pcrread), buffer, sizeof(buffer)); + + g_assert_cmpmem(buffer, exp_resp_size, exp_resp, exp_resp_size); +} + +static gboolean tpm_util_swtpm_has_tpm2(void) +{ + gint stdout; + gboolean succ; + unsigned i; + char buffer[10240]; + ssize_t n; + gchar *swtpm_argv[] =3D { + g_strdup("swtpm"), g_strdup("socket"), g_strdup("--help"), NULL + }; + + succ =3D g_spawn_async_with_pipes(NULL, swtpm_argv, NULL, + G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, + NULL, &stdout, NULL, NULL); + if (!succ) { + goto cleanup; + } + + n =3D read(stdout, buffer, sizeof(buffer) - 1); + if (n < 0) { + goto cleanup; + } + buffer[n] =3D 0; + if (!strstr(buffer, "--tpm2")) { + succ =3D false; + } + + cleanup: + for (i =3D 0; swtpm_argv[i]; i++) { + g_free(swtpm_argv[i]); + } + + return succ; +} + +gboolean tpm_util_swtpm_start(const char *path, GPid *pid, + SocketAddress **addr, GError **error) +{ + char *swtpm_argv_tpmstate =3D g_strdup_printf("dir=3D%s", path); + char *swtpm_argv_ctrl =3D g_strdup_printf("type=3Dunixio,path=3D%s/soc= k", + path); + gchar *swtpm_argv[] =3D { + g_strdup("swtpm"), g_strdup("socket"), + g_strdup("--tpmstate"), swtpm_argv_tpmstate, + g_strdup("--ctrl"), swtpm_argv_ctrl, + g_strdup("--tpm2"), + NULL + }; + gboolean succ; + unsigned i; + + succ =3D tpm_util_swtpm_has_tpm2(); + if (!succ) { + goto cleanup; + } + + *addr =3D g_new0(SocketAddress, 1); + (*addr)->type =3D SOCKET_ADDRESS_TYPE_UNIX; + (*addr)->u.q_unix.path =3D g_build_filename(path, "sock", NULL); + + succ =3D g_spawn_async(NULL, swtpm_argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, pid, error); + +cleanup: + for (i =3D 0; swtpm_argv[i]; i++) { + g_free(swtpm_argv[i]); + } + + return succ; +} + +void tpm_util_swtpm_kill(GPid pid) +{ + int n; + + if (!pid) { + return; + } + + g_spawn_close_pid(pid); + + n =3D kill(pid, 0); + if (n < 0) { + return; + } + + kill(pid, SIGKILL); +} diff --git a/tests/tpm-util.h b/tests/tpm-util.h new file mode 100644 index 0000000..d155d99 --- /dev/null +++ b/tests/tpm-util.h @@ -0,0 +1,36 @@ +/* + * QTest TPM utilities + * + * Copyright (c) 2018 IBM Corporation + * + * Authors: + * Stefan Berger + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef TESTS_TPM_UTIL_H +#define TESTS_TPM_UTIL_H + +#include "qemu/osdep.h" +#include "io/channel-socket.h" + +typedef void (tx_func)(QTestState *s, + const unsigned char *req, size_t req_size, + unsigned char *rsp, size_t rsp_size); + +void tpm_util_crb_transfer(QTestState *s, + const unsigned char *req, size_t req_size, + unsigned char *rsp, size_t rsp_size); + +void tpm_util_startup(QTestState *s, tx_func *tx); +void tpm_util_pcrextend(QTestState *s, tx_func *tx); +void tpm_util_pcrread(QTestState *s, tx_func *tx, + const unsigned char *exp_resp, size_t exp_resp_size); + +gboolean tpm_util_swtpm_start(const char *path, GPid *pid, + SocketAddress **addr, GError **error); +void tpm_util_swtpm_kill(GPid pid); + +#endif /* TESTS_TPM_UTIL_H */ --=20 2.5.5