From nobody Mon Feb 9 02:51:12 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1562948667; cv=none; d=zoho.com; s=zohoarc; b=mYzyikRo3o+swpE0VI4BkXYfv8yAS6NgOH5X958O63uYaiw2vbGpxbK457WCf3I/NWg3O9fZ+cm23IsNie3bHcFQFuPryTiHPC2eh9a6rYQaAiWXdtQ00AhVGELGOTewRNOLw8T+lNRNh3Z/DbkV4ZaCVPUS51hmAzXqib+dD8U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562948667; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=806KBhDLRB/KKkZvih77td/gj6EEezqKho8JxWsWvIg=; b=gv2+WCx3VUlUcl7t8yQU+MV+9diqXOMESCMQg4nrMzxfIas3njLwU6b45Ls+lv8zxOw945OhBKgfQChvxGnNK5mNw4umX4fI6TsGE65coZbmslq/UXyf/98E2sKsEci1vlVD+lYxf6fcRmfs3m80anRYFdCuTxjc2Qf3fdCNXKI= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1562948667863713.9027000862691; Fri, 12 Jul 2019 09:24:27 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 20E653099FC5; Fri, 12 Jul 2019 16:24:26 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EBA805B684; Fri, 12 Jul 2019 16:24:25 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AEDE6206D3; Fri, 12 Jul 2019 16:24:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x6CGO4LZ020157 for ; Fri, 12 Jul 2019 12:24:04 -0400 Received: by smtp.corp.redhat.com (Postfix) id 686CD608C2; Fri, 12 Jul 2019 16:24:04 +0000 (UTC) Received: from mx1.redhat.com (ext-mx19.extmail.prod.ext.phx2.redhat.com [10.5.110.48]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5D44E60920 for ; Fri, 12 Jul 2019 16:24:04 +0000 (UTC) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A6FB3307D85E for ; Fri, 12 Jul 2019 16:24:03 +0000 (UTC) Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x6CGHJG0099062 for ; Fri, 12 Jul 2019 12:24:03 -0400 Received: from e12.ny.us.ibm.com (e12.ny.us.ibm.com [129.33.205.202]) by mx0a-001b2d01.pphosted.com with ESMTP id 2tpw8y16b9-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 12 Jul 2019 12:24:03 -0400 Received: from localhost by e12.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 12 Jul 2019 17:24:02 +0100 Received: from b01cxnp22035.gho.pok.ibm.com (9.57.198.25) by e12.ny.us.ibm.com (146.89.104.199) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 12 Jul 2019 17:23:59 +0100 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp22035.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x6CGNwEL51183966 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 12 Jul 2019 16:23:58 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 07ABFAC062; Fri, 12 Jul 2019 16:23:58 +0000 (GMT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E37FEAC05E; Fri, 12 Jul 2019 16:23:57 +0000 (GMT) Received: from sbct-3.pok.ibm.com (unknown [9.47.158.153]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP; Fri, 12 Jul 2019 16:23:57 +0000 (GMT) From: Stefan Berger To: libvir-list@redhat.com Date: Fri, 12 Jul 2019 12:23:50 -0400 In-Reply-To: <20190712162354.2366936-1-stefanb@linux.vnet.ibm.com> References: <20190712162354.2366936-1-stefanb@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 19071216-0060-0000-0000-0000035DCA7A X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00011415; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000286; SDB=6.01231169; UDB=6.00648543; IPR=6.01012454; MB=3.00027693; MTD=3.00000008; XFM=3.00000015; UTC=2019-07-12 16:24:00 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19071216-0061-0000-0000-00004A1D357F Message-Id: <20190712162354.2366936-17-stefanb@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-07-12_04:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1907120170 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 238 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 12 Jul 2019 16:24:03 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 12 Jul 2019 16:24:03 +0000 (UTC) for IP:'148.163.156.1' DOMAIN:'mx0a-001b2d01.pphosted.com' HELO:'mx0a-001b2d01.pphosted.com' FROM:'stefanb@linux.vnet.ibm.com' RCPT:'' X-RedHat-Spam-Score: -0.698 (RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE) 148.163.156.1 mx0a-001b2d01.pphosted.com 148.163.156.1 mx0a-001b2d01.pphosted.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.48 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Cc: marcandre.lureau@redhat.com, Stefan Berger Subject: [libvirt] [PATCH v5 16/20] tpm: Use fd to pass password to swtpm_setup and swtpm X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 12 Jul 2019 16:24:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Allow vTPM state encryption when swtpm_setup and swtpm support passing a passphrase using a file descriptor. This patch enables the encryption of the vTPM state only. It does not encrypt the state during migration, so the destination secret does not need to have the same password at this point. Signed-off-by: Stefan Berger Reviewed-by: Daniel P. Berrang=C3=A9 --- src/libvirt_private.syms | 2 + src/qemu/qemu_tpm.c | 110 ++++++++++++++++++++++++++++++++++++++- src/util/virtpm.c | 16 ++++++ src/util/virtpm.h | 3 ++ 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 13829563e9..b531ab1efa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3182,7 +3182,9 @@ virTPMEmulatorInit; virTPMGetSwtpm; virTPMGetSwtpmIoctl; virTPMGetSwtpmSetup; +virTPMSwtpmCapsGet; virTPMSwtpmFeatureTypeFromString; +virTPMSwtpmSetupCapsGet; virTPMSwtpmSetupFeatureTypeFromString; =20 =20 diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c index 2afa8db448..3bec68bce6 100644 --- a/src/qemu/qemu_tpm.c +++ b/src/qemu/qemu_tpm.c @@ -43,6 +43,7 @@ #include "dirname.h" #include "qemu_tpm.h" #include "virtpm.h" +#include "secret_util.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 @@ -372,6 +373,66 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm, return ret; } =20 +/* + * qemuTPMSetupEncryption + * + * @secretuuid: The UUID with the secret holding passphrase + * @cmd: the virCommand to transfer the secret to + * + * Returns file descriptor representing the read-end of a pipe. + * The passphrase can be read from this pipe. Returns < 0 in case + * of error. + * + * This function reads the passphrase and writes it into the + * write-end of a pipe so that the read-end of the pipe can be + * passed to the emulator for reading the passphrase from. + */ +static int +qemuTPMSetupEncryption(const unsigned char *secretuuid, + virCommandPtr cmd) +{ + int ret =3D -1; + int pipefd[2] =3D { -1, -1 }; + virConnectPtr conn; + VIR_AUTOFREE(uint8_t *) secret =3D NULL; + size_t secret_len; + virSecretLookupTypeDef seclookupdef =3D { + .type =3D VIR_SECRET_LOOKUP_TYPE_UUID, + }; + + conn =3D virGetConnectSecret(); + if (!conn) + return -1; + + memcpy(seclookupdef.u.uuid, secretuuid, sizeof(seclookupdef.u.uuid)); + if (virSecretGetSecretString(conn, &seclookupdef, + VIR_SECRET_USAGE_TYPE_VTPM, + &secret, &secret_len) < 0) + goto error; + + if (pipe(pipefd) =3D=3D -1) { + virReportSystemError(errno, "%s", + _("Unable to create pipe")); + goto error; + } + + if (virCommandSetSendBuffer(cmd, pipefd[1], secret, secret_len) < 0) + goto error; + + secret =3D NULL; + ret =3D pipefd[0]; + + cleanup: + virObjectUnref(conn); + + return ret; + + error: + VIR_FORCE_CLOSE(pipefd[1]); + VIR_FORCE_CLOSE(pipefd[0]); + + goto cleanup; +} =20 /* * qemuTPMEmulatorRunSetup @@ -386,6 +447,7 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm, * @logfile: The file to write the log into; it must be writable * for the user given by userid or 'tss' * @tpmversion: The version of the TPM, either a TPM 1.2 or TPM 2 + * @encryption: pointer to virStorageEncryption holding secret * * Setup the external swtpm by creating endorsement key and * certificates for it. @@ -398,13 +460,15 @@ qemuTPMEmulatorRunSetup(const char *storagepath, uid_t swtpm_user, gid_t swtpm_group, const char *logfile, - const virDomainTPMVersion tpmversion) + const virDomainTPMVersion tpmversion, + const unsigned char *secretuuid) { virCommandPtr cmd =3D NULL; int exitstatus; int ret =3D -1; char uuid[VIR_UUID_STRING_BUFLEN]; char *vmid =3D NULL; + VIR_AUTOCLOSE pwdfile_fd =3D -1; =20 if (!privileged && tpmversion =3D=3D VIR_DOMAIN_TPM_VERSION_1_2) return virFileWriteStr(logfile, @@ -434,6 +498,23 @@ qemuTPMEmulatorRunSetup(const char *storagepath, break; } =20 + if (secretuuid) { + if (!virTPMSwtpmSetupCapsGet( + VIR_TPM_SWTPM_SETUP_FEATURE_CMDARG_PWDFILE_FD)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("%s does not support passing a passphrase using a file " + "descriptor"), virTPMGetSwtpmSetup()); + goto cleanup; + } + if ((pwdfile_fd =3D qemuTPMSetupEncryption(secretuuid, cmd)) < 0) + goto cleanup; + + virCommandAddArg(cmd, "--pwdfile-fd"); + virCommandAddArgFormat(cmd, "%d", pwdfile_fd); + virCommandAddArgList(cmd, "--cipher", "aes-256-cbc", NULL); + virCommandPassFD(cmd, pwdfile_fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT= ); + pwdfile_fd =3D -1; + } =20 virCommandAddArgList(cmd, "--tpm-state", storagepath, @@ -496,15 +577,21 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, virCommandPtr cmd =3D NULL; bool created =3D false; char *pidfile; + VIR_AUTOCLOSE pwdfile_fd =3D -1; + const unsigned char *secretuuid =3D NULL; =20 if (qemuTPMCreateEmulatorStorage(tpm->data.emulator.storagepath, &created, swtpm_user, swtpm_group) < = 0) return NULL; =20 + if (tpm->data.emulator.hassecretuuid) + secretuuid =3D tpm->data.emulator.secretuuid; + if (created && qemuTPMEmulatorRunSetup(tpm->data.emulator.storagepath, vmname, vm= uuid, privileged, swtpm_user, swtpm_group, - tpm->data.emulator.logfile, tpm->version) = < 0) + tpm->data.emulator.logfile, tpm->version, + secretuuid) < 0) goto error; =20 unlink(tpm->data.emulator.source.data.nix.path); @@ -547,6 +634,25 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, virCommandAddArgFormat(cmd, "file=3D%s", pidfile); VIR_FREE(pidfile); =20 + if (tpm->data.emulator.hassecretuuid) { + if (!virTPMSwtpmCapsGet(VIR_TPM_SWTPM_FEATURE_CMDARG_PWD_FD)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("%s does not support passing passphrase via file descr= iptor"), + virTPMGetSwtpm()); + goto error; + } + + pwdfile_fd =3D qemuTPMSetupEncryption(tpm->data.emulator.secretuui= d, cmd); + if (pwdfile_fd) + goto error; + + virCommandAddArg(cmd, "--key"); + virCommandAddArgFormat(cmd, "pwdfd=3D%d,mode=3Daes-256-cbc,kdf=3Dp= bkdf2", + pwdfile_fd); + virCommandPassFD(cmd, pwdfile_fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT= ); + pwdfile_fd =3D -1; + } + return cmd; =20 error: diff --git a/src/util/virtpm.c b/src/util/virtpm.c index 692033e899..eda16a8c57 100644 --- a/src/util/virtpm.c +++ b/src/util/virtpm.c @@ -317,3 +317,19 @@ virTPMEmulatorInit(void) =20 return 0; } + +bool +virTPMSwtpmCapsGet(unsigned int cap) +{ + if (virTPMEmulatorInit() < 0) + return false; + return virBitmapIsBitSet(swtpm_caps, cap); +} + +bool +virTPMSwtpmSetupCapsGet(unsigned int cap) +{ + if (virTPMEmulatorInit() < 0) + return false; + return virBitmapIsBitSet(swtpm_setup_caps, cap); +} diff --git a/src/util/virtpm.h b/src/util/virtpm.h index f3dc40cd68..40bde4c666 100644 --- a/src/util/virtpm.h +++ b/src/util/virtpm.h @@ -27,6 +27,9 @@ const char *virTPMGetSwtpmSetup(void); const char *virTPMGetSwtpmIoctl(void); int virTPMEmulatorInit(void); =20 +bool virTPMSwtpmCapsGet(unsigned int cap); +bool virTPMSwtpmSetupCapsGet(unsigned int cap); + typedef enum { VIR_TPM_SWTPM_FEATURE_CMDARG_PWD_FD, =20 --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list