From nobody Sun Feb 8 16:30:49 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=1562694774; cv=none; d=zoho.com; s=zohoarc; b=hJ6my/nHAxnYC1m/T869Y+RmK9fLihsJskC6SMly78jWNhYxEGgsBzvOOhKz2o584vl7jK0eXoMYoWp0XSSLy4OHhcrWOxa61Drjuwkt90EblekAa6uVuR9oX1rZHAbE+7EImTKOWiKh5eXc+T3L2AgtE2qJliojDfc+PtXdSAA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562694774; 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=I5uWwp0o7uxKeGNxVsD6P1Sp5b4zGaRI9v345EbbLjw=; b=O+w6/aVRXuZxMd7sN+FbqKVVWRc89SyeRrZue0wSvHl/rZaV94WGUszAH1jc1Lr0kUVuiUgrJAkIi9xZRsJ8Ny1ZVyGZaqNoCgSLYt53qc4uuCPZ7aO+3qLpFxxhkebYx4VeuCv6j5d6fGW2ogSHGLYrioMAv5W0osKHOI90m/w= 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 1562694774794689.0256237227459; Tue, 9 Jul 2019 10:52:54 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id ED2592EF16E; Tue, 9 Jul 2019 17:52:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C76052BFA0; Tue, 9 Jul 2019 17:52:45 +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 5DD9F1833002; Tue, 9 Jul 2019 17:52:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x69HqeQ9000703 for ; Tue, 9 Jul 2019 13:52:40 -0400 Received: by smtp.corp.redhat.com (Postfix) id 1F2272BFA0; Tue, 9 Jul 2019 17:52:40 +0000 (UTC) Received: from mx1.redhat.com (ext-mx09.extmail.prod.ext.phx2.redhat.com [10.5.110.38]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1AA7C5B80B for ; Tue, 9 Jul 2019 17:52:37 +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 50838F9E8E for ; Tue, 9 Jul 2019 17:52:21 +0000 (UTC) Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x69HMO05114817; Tue, 9 Jul 2019 13:23:46 -0400 Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 2tmy5d87yc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 09 Jul 2019 13:23:46 -0400 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id x69HJmQI002093; Tue, 9 Jul 2019 17:23:45 GMT Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by ppma03dal.us.ibm.com with ESMTP id 2tjk96pk98-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 09 Jul 2019 17:23:45 +0000 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x69HNigo42992088 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 9 Jul 2019 17:23:44 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2DF60112061; Tue, 9 Jul 2019 17:23:44 +0000 (GMT) Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0CA10112062; Tue, 9 Jul 2019 17:23:44 +0000 (GMT) Received: from sbct-3.pok.ibm.com (unknown [9.47.158.153]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP; Tue, 9 Jul 2019 17:23:43 +0000 (GMT) From: Stefan Berger To: libvir-list@redhat.com Date: Tue, 9 Jul 2019 13:23:37 -0400 Message-Id: <20190709172341.3063264-15-stefanb@linux.vnet.ibm.com> In-Reply-To: <20190709172341.3063264-1-stefanb@linux.vnet.ibm.com> References: <20190709172341.3063264-1-stefanb@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-07-09_07:, , 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-1907090205 X-Greylist: Delayed for 00:28:35 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 09 Jul 2019 17:52:21 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 09 Jul 2019 17:52:21 +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.78 on 10.5.110.38 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: marcandre.lureau@redhat.com, Stefan Berger Subject: [libvirt] [PATCH 14/18] 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 09 Jul 2019 17:52:53 +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 --- src/libvirt_private.syms | 2 + src/qemu/qemu_tpm.c | 101 ++++++++++++++++++++++++++++++++++++++- src/tpm/virtpm.c | 16 +++++++ src/tpm/virtpm.h | 3 ++ 4 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d2045895a1..d693f7facb 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1456,6 +1456,8 @@ virTPMEmulatorInit; virTPMGetSwtpm; virTPMGetSwtpmIoctl; virTPMGetSwtpmSetup; +virTPMSwtpmCapsGet; +virTPMSwtpmSetupCapsGet; =20 =20 # util/viralloc.h diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c index 2afa8db448..6e7d38b7e0 100644 --- a/src/qemu/qemu_tpm.c +++ b/src/qemu/qemu_tpm.c @@ -43,6 +43,8 @@ #include "dirname.h" #include "qemu_tpm.h" #include "virtpm.h" +#include "secret_util.h" +#include "virtpm_conf.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 @@ -372,6 +374,60 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm, return ret; } =20 +/* + * qemuTPMSetupEncryption + * + * @encryption: pointer to virStorageEncryption holding secret + * + * 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(virStorageEncryptionPtr encryption) +{ + int ret =3D -1; + int pipefd[2] =3D { -1, -1 }; + virConnectPtr conn; + uint8_t *secret =3D NULL; + size_t secret_len; + + conn =3D virGetConnectSecret(); + if (!conn) + return -1; + + if (virSecretGetSecretString(conn, &encryption->secrets[0]->seclookupd= ef, + 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 (safewrite(pipefd[1], secret, secret_len) !=3D secret_len) + goto error; + + ret =3D pipefd[0]; + + cleanup: + VIR_FREE(secret); + VIR_FORCE_CLOSE(pipefd[1]); + virObjectUnref(conn); + + return ret; + + error: + VIR_FORCE_CLOSE(pipefd[0]); + + goto cleanup; +} =20 /* * qemuTPMEmulatorRunSetup @@ -386,6 +442,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 +455,15 @@ qemuTPMEmulatorRunSetup(const char *storagepath, uid_t swtpm_user, gid_t swtpm_group, const char *logfile, - const virDomainTPMVersion tpmversion) + const virDomainTPMVersion tpmversion, + virStorageEncryptionPtr encryption) { virCommandPtr cmd =3D NULL; int exitstatus; int ret =3D -1; char uuid[VIR_UUID_STRING_BUFLEN]; char *vmid =3D NULL; + int pwdfile_fd =3D -1; =20 if (!privileged && tpmversion =3D=3D VIR_DOMAIN_TPM_VERSION_1_2) return virFileWriteStr(logfile, @@ -434,6 +493,22 @@ qemuTPMEmulatorRunSetup(const char *storagepath, break; } =20 + if (encryption) { + 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(encryption)) < 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= ); + } =20 virCommandAddArgList(cmd, "--tpm-state", storagepath, @@ -461,6 +536,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath, cleanup: VIR_FREE(vmid); virCommandFree(cmd); + VIR_FORCE_CLOSE(pwdfile_fd); =20 return ret; } @@ -496,6 +572,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, virCommandPtr cmd =3D NULL; bool created =3D false; char *pidfile; + int pwdfile_fd =3D -1; =20 if (qemuTPMCreateEmulatorStorage(tpm->data.emulator.storagepath, &created, swtpm_user, swtpm_group) < = 0) @@ -504,7 +581,8 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, 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, + tpm->data.emulator.encryption) < 0) goto error; =20 unlink(tpm->data.emulator.source.data.nix.path); @@ -547,11 +625,30 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, virCommandAddArgFormat(cmd, "file=3D%s", pidfile); VIR_FREE(pidfile); =20 + if (tpm->data.emulator.encryption) { + 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.encryptio= n); + if (pwdfile_fd < 0) + 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= ); + } + return cmd; =20 error: if (created) qemuTPMDeleteEmulatorStorage(tpm); + VIR_FORCE_CLOSE(pwdfile_fd); =20 virCommandFree(cmd); =20 diff --git a/src/tpm/virtpm.c b/src/tpm/virtpm.c index 42dd2b1bb2..7e95dbad6f 100644 --- a/src/tpm/virtpm.c +++ b/src/tpm/virtpm.c @@ -312,3 +312,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/tpm/virtpm.h b/src/tpm/virtpm.h index 66d55fb231..a8bb6e1ba0 100644 --- a/src/tpm/virtpm.h +++ b/src/tpm/virtpm.h @@ -26,3 +26,6 @@ const char *virTPMGetSwtpm(void); const char *virTPMGetSwtpmSetup(void); const char *virTPMGetSwtpmIoctl(void); int virTPMEmulatorInit(void); + +bool virTPMSwtpmCapsGet(unsigned int cap); +bool virTPMSwtpmSetupCapsGet(unsigned int cap); --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list