From nobody Thu May 9 18:03:01 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1707841183619875.3832287267612; Tue, 13 Feb 2024 08:19:43 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id 8CA311B4A; Tue, 13 Feb 2024 11:19:42 -0500 (EST) Received: from lists.libvirt.org.85.43.8.in-addr.arpa (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id C996C1A81; Tue, 13 Feb 2024 11:16:22 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 458EE19C6; Tue, 13 Feb 2024 11:16:14 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 4247F19C5 for ; Tue, 13 Feb 2024 11:16:13 -0500 (EST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-551-ffsrDW_EOlu1C26t4_aHtg-1; Tue, 13 Feb 2024 11:16:11 -0500 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4DD1784B04E for ; Tue, 13 Feb 2024 16:16:11 +0000 (UTC) Received: from maggie.brq.redhat.com (unknown [10.43.3.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id EA7D1492C2F for ; Tue, 13 Feb 2024 16:16:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: ffsrDW_EOlu1C26t4_aHtg-1 From: Michal Privoznik To: devel@lists.libvirt.org Subject: [PATCH 1/4] virsecret: Introduce APIs to talk to systemd-cred Date: Tue, 13 Feb 2024 17:16:05 +0100 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: PWXEYI4PBI76FY4D3QNNNGLGHGWDQYSR X-Message-ID-Hash: PWXEYI4PBI76FY4D3QNNNGLGHGWDQYSR X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8"; x-default="true" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1707841185432100001 The systemd-cred offers a convenient way to talk to host's TPM. While its original intent is to be used in systemd unit files, it offers two additional commands: encrypt and decrypt that can be used independent of the rest of systemd. And these are the ones we need. They offer a convenient way to encrypt/decrypt plaintext using a key that's stored in host's TPM (when --with-key=3Dtpm is passed). In addition, there's 'has-tpm2' command which allows us to detect whether host and the OS have everything needed to utilize the TPM. Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 3 + src/util/virsecret.c | 170 +++++++++++++++++++++++++++++++++++++++ src/util/virsecret.h | 10 +++ 3 files changed, 183 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 396bd80844..1d1bba915a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3362,6 +3362,9 @@ virSecretLookupDefClear; virSecretLookupDefCopy; virSecretLookupFormatSecret; virSecretLookupParseSecret; +virSecretTPMAvailable; +virSecretTPMDecrypt; +virSecretTPMEncrypt; =20 =20 # util/virsecureerase.h diff --git a/src/util/virsecret.c b/src/util/virsecret.c index 8a220a37ec..11aa146b6d 100644 --- a/src/util/virsecret.c +++ b/src/util/virsecret.c @@ -23,10 +23,13 @@ =20 #include "datatypes.h" #include "viralloc.h" +#include "vircommand.h" #include "virerror.h" #include "virlog.h" #include "virsecret.h" +#include "virutil.h" #include "viruuid.h" +#include "virfile.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 @@ -176,3 +179,170 @@ virSecretGetSecretString(virConnectPtr conn, =20 return 0; } + + +/** + * virSecretTPMAvailable: + * + * Checks whether systemd-creds is available and whether host supports + * TPM. Use this prior calling other virSecretTPM*() APIs. + * + * Returns: 1 in case TPM is available, + * 0 in case TPM is NOT available, + * -1 otherwise. + */ +int +virSecretTPMAvailable(void) +{ + g_autoptr(virCommand) cmd =3D NULL; + g_autofree char *out =3D NULL; + int exitstatus; + int rc; + + cmd =3D virCommandNewArgList("systemd-creds", "has-tpm2", NULL); + + virCommandSetOutputBuffer(cmd, &out); + + rc =3D virCommandRun(cmd, &exitstatus); + + if (rc < 0) { + /* systemd-creds not available */ + return -1; + } + + if (!out || !*out) { + /* systemd-creds reported nothing. Ouch. */ + return 0; + } + + /* systemd-creds can report one of these: + * + * yes - TPM is available and recognized by FW, kernel, etc. + * no - TPM is not available or not recognized + * partial - otherwise + */ + + if (STRPREFIX(out, "yes\n")) + return 1; + + return 0; +} + + +/** + * virSecretTPMEncrypt: + * @name: credential name + * @value: credential value + * @value_size: size of @value + * @base64: encrypted @value, base64 encoded + * + * Encrypts given plaintext (@value) with a secret key automatically + * derived from the system's TPM2 chip. Ciphertext is base64 encoded and + * stored into @base64. Pass the same @name to virSecretTPMDecrypt(). + * + * Returns: 0 on success, + * -1 otherwise (with error reported). + */ +int +virSecretTPMEncrypt(const char *name, + unsigned const char *value, + size_t value_size, + char **base64) +{ + g_autoptr(virCommand) cmd =3D NULL; + g_autofree char *errBuf =3D NULL; + int pipeFD[2] =3D { -1, -1 }; + int ret =3D -1; + + if (virPipe(pipeFD) < 0) + return -1; + + if (virSetCloseExec(pipeFD[1]) < 0) { + virReportSystemError(errno, "%s", + _("Unable to set cloexec flag")); + goto cleanup; + } + + cmd =3D virCommandNewArgList("systemd-creds", "encrypt", + "--with-key=3Dtpm2", NULL); + virCommandAddArgFormat(cmd, "--name=3D%s", name); + virCommandAddArgList(cmd, "-", "-", NULL); + + virCommandSetInputFD(cmd, pipeFD[0]); + virCommandSetOutputBuffer(cmd, base64); + virCommandSetErrorBuffer(cmd, &errBuf); + virCommandDoAsyncIO(cmd); + + if (virCommandRunAsync(cmd, NULL) < 0) + goto cleanup; + + if (safewrite(pipeFD[1], value, value_size) !=3D value_size) { + virReportSystemError(errno, "%s", + _("Unable to pass secret value to systemd-cre= d")); + goto cleanup; + } + + if (VIR_CLOSE(pipeFD[1]) < 0) { + virReportSystemError(errno, "%s", _("unable to close pipe")); + goto cleanup; + } + + if (virCommandWait(cmd, NULL) < 0) { + if (errBuf && *errBuf) { + VIR_WARN("systemd-creds reported: %s", errBuf); + } + goto cleanup; + } + + ret =3D 0; + cleanup: + virCommandAbort(cmd); + VIR_FORCE_CLOSE(pipeFD[0]); + VIR_FORCE_CLOSE(pipeFD[1]); + return ret; +} + + +/** + * virSecretTPMDecrypt: + * @name: credential name + * @base64: encrypted @value, base64 encoded + * @value: credential value, + * @value_size: size of @value + * + * Decrypts given ciphertext, base64 encoded (@base64) and stores + * plaintext into @value and its size into @value_size. + * + * Returns: 0 on success, + * -1 otherwise (with error reported). + */ +int +virSecretTPMDecrypt(const char *name, + const char *base64, + unsigned char **value, + size_t *value_size) +{ + g_autoptr(virCommand) cmd =3D NULL; + g_autofree char *out =3D NULL; + g_autofree char *errBuf =3D NULL; + + cmd =3D virCommandNewArgList("systemd-creds", "decrypt", + "--transcode=3Dbase64", NULL); + virCommandAddArgFormat(cmd, "--name=3D%s", name); + virCommandAddArgList(cmd, "-", "-", NULL); + + virCommandSetInputBuffer(cmd, base64); + virCommandSetOutputBuffer(cmd, &out); + virCommandSetErrorBuffer(cmd, &errBuf); + + if (virCommandRun(cmd, NULL) < 0) { + if (errBuf && *errBuf) { + VIR_WARN("systemd-creds reported: %s", errBuf); + } + return -1; + } + + *value =3D g_base64_decode(out, value_size); + + return 0; +} diff --git a/src/util/virsecret.h b/src/util/virsecret.h index c803f0fe33..a5ca764bb7 100644 --- a/src/util/virsecret.h +++ b/src/util/virsecret.h @@ -62,3 +62,13 @@ int virSecretGetSecretString(virConnectPtr conn, size_t *ret_secret_size) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) G_GNUC_WARN_UNUSED_RESULT; + +int virSecretTPMAvailable(void); +int virSecretTPMEncrypt(const char *name, + unsigned const char *value, + size_t value_size, + char **base64); +int virSecretTPMDecrypt(const char *name, + const char *base64, + unsigned char **value, + size_t *value_size); --=20 2.43.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org From nobody Thu May 9 18:03:01 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1707841300906584.238152872028; Tue, 13 Feb 2024 08:21:40 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id C14D11A6C; Tue, 13 Feb 2024 11:21:39 -0500 (EST) Received: from lists.libvirt.org.85.43.8.in-addr.arpa (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 460DE1A2F; Tue, 13 Feb 2024 11:16:33 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id D661419C4; Tue, 13 Feb 2024 11:16:14 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id D5E2119BF for ; Tue, 13 Feb 2024 11:16:13 -0500 (EST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-29-ft6mw-fOO2Siz5_X1vrBoA-1; Tue, 13 Feb 2024 11:16:12 -0500 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DB332108BE9B for ; Tue, 13 Feb 2024 16:16:11 +0000 (UTC) Received: from maggie.brq.redhat.com (unknown [10.43.3.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id 839C1492C2D for ; Tue, 13 Feb 2024 16:16:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: ft6mw-fOO2Siz5_X1vrBoA-1 From: Michal Privoznik To: devel@lists.libvirt.org Subject: [PATCH 2/4] conf: Introduce @tpm attribute to Date: Tue, 13 Feb 2024 17:16:06 +0100 Message-ID: <5169aca197a3193014e32dee67dbc3ac997478b2.1707840643.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: 4HQXJSW3MUUP2Z3OI2P3GOGAIMFW7ZYJ X-Message-ID-Hash: 4HQXJSW3MUUP2Z3OI2P3GOGAIMFW7ZYJ X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8"; x-default="true" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1707841301933100001 This attribute exists next to @ephemeral and @private attributes and controls whether the secret value is encrypted using system's TPM chip before stored on disk. Obviously, it's mutually exclusive with @ephemeral which forces us to keep the secret value in memory only. In the long run, we can even encrypt secret values that are kept in memory (so they can't be obtained by dumping virtsecretd's memory). But that's not what is being implemented here. Signed-off-by: Michal Privoznik --- docs/formatsecret.rst | 8 ++++++-- src/conf/schemas/secret.rng | 5 +++++ src/conf/secret_conf.c | 17 +++++++++++++++++ src/conf/secret_conf.h | 2 ++ tests/secretxml2xmlin/usage-tpm-vtpm.xml | 7 +++++++ tests/secretxml2xmltest.c | 1 + 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/secretxml2xmlin/usage-tpm-vtpm.xml diff --git a/docs/formatsecret.rst b/docs/formatsecret.rst index d0c37ff165..c7910aecce 100644 --- a/docs/formatsecret.rst +++ b/docs/formatsecret.rst @@ -10,14 +10,18 @@ Secret XML ---------- =20 Secrets stored by libvirt may have attributes associated with them, using = the -``secret`` element. The ``secret`` element has two optional attributes, ea= ch -with values '``yes``' and '``no``', and defaulting to '``no``': +``secret`` element. The ``secret`` element has the following optional +attributes, each with values '``yes``' and '``no``', and defaulting to +'``no``': =20 ``ephemeral`` This secret must only be kept in memory, never stored persistently. ``private`` The value of the secret must not be revealed to any caller of libvirt, = nor to any other node. +``tpm`` + The value of the secret is stored using a key that's derived from the + system's TPM2 chip. This is mutually exclusive with ``ephemeral``. =20 The top-level ``secret`` element may contain the following elements: =20 diff --git a/src/conf/schemas/secret.rng b/src/conf/schemas/secret.rng index c90e2eb81f..59d825bf91 100644 --- a/src/conf/schemas/secret.rng +++ b/src/conf/schemas/secret.rng @@ -19,6 +19,11 @@ + + + + + diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c index 966536599e..1ab6cf5cd4 100644 --- a/src/conf/secret_conf.c +++ b/src/conf/secret_conf.c @@ -130,6 +130,7 @@ virSecretParseXML(xmlXPathContext *ctxt) g_autoptr(virSecretDef) def =3D NULL; g_autofree char *ephemeralstr =3D NULL; g_autofree char *privatestr =3D NULL; + g_autofree char *tpmstr =3D NULL; g_autofree char *uuidstr =3D NULL; =20 def =3D g_new0(virSecretDef, 1); @@ -150,6 +151,17 @@ virSecretParseXML(xmlXPathContext *ctxt) } } =20 + if (virXMLPropTristateBool(ctxt->node, "tpm", + VIR_XML_PROP_NONE, &def->tpm) < 0) { + return NULL; + } + + if (def->tpm =3D=3D VIR_TRISTATE_BOOL_YES && def->isephemeral) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ephemeral and tpm are mutually exclusive")); + return NULL; + } + uuidstr =3D virXPathString("string(./uuid)", ctxt); if (!uuidstr) { if (virUUIDGenerate(def->uuid) < 0) { @@ -248,6 +260,11 @@ virSecretDefFormat(const virSecretDef *def) def->isephemeral ? "yes" : "no", def->isprivate ? "yes" : "no"); =20 + if (def->tpm !=3D VIR_TRISTATE_BOOL_ABSENT) { + virBufferAsprintf(&attrBuf, " tpm=3D'%s'", + virTristateBoolTypeToString(def->tpm)); + } + virUUIDFormat(def->uuid, uuidstr); virBufferEscapeString(&childBuf, "%s\n", uuidstr); if (def->description !=3D NULL) diff --git a/src/conf/secret_conf.h b/src/conf/secret_conf.h index 8f8f47933a..8a9e382c1e 100644 --- a/src/conf/secret_conf.h +++ b/src/conf/secret_conf.h @@ -21,11 +21,13 @@ #pragma once =20 #include "internal.h" +#include "virenum.h" =20 typedef struct _virSecretDef virSecretDef; struct _virSecretDef { bool isephemeral; bool isprivate; + virTristateBool tpm; unsigned char uuid[VIR_UUID_BUFLEN]; char *description; /* May be NULL */ virSecretUsageType usage_type; diff --git a/tests/secretxml2xmlin/usage-tpm-vtpm.xml b/tests/secretxml2xml= in/usage-tpm-vtpm.xml new file mode 100644 index 0000000000..b70785113c --- /dev/null +++ b/tests/secretxml2xmlin/usage-tpm-vtpm.xml @@ -0,0 +1,7 @@ + + 46b96412-fffc-46a3-bf3d-c371f776cadb + vTPM secret + + vTPMvTPMvTPM + + diff --git a/tests/secretxml2xmltest.c b/tests/secretxml2xmltest.c index eb4d3e143c..cdd34546b2 100644 --- a/tests/secretxml2xmltest.c +++ b/tests/secretxml2xmltest.c @@ -69,6 +69,7 @@ mymain(void) DO_TEST("usage-iscsi"); DO_TEST("usage-tls"); DO_TEST("usage-vtpm"); + DO_TEST("usage-tpm-vtpm"); =20 return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } --=20 2.43.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org From nobody Thu May 9 18:03:01 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1707841435840414.0089732064599; Tue, 13 Feb 2024 08:23:55 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id B453819C0; Tue, 13 Feb 2024 11:23:54 -0500 (EST) Received: from lists.libvirt.org.85.43.8.in-addr.arpa (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 064611B70; Tue, 13 Feb 2024 11:16:42 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 5118119BF; Tue, 13 Feb 2024 11:16:15 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 7647219C5 for ; Tue, 13 Feb 2024 11:16:14 -0500 (EST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-647-TBzmYK2EPr6OlMU1XCyLlQ-1; Tue, 13 Feb 2024 11:16:12 -0500 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 740E885A58E for ; Tue, 13 Feb 2024 16:16:12 +0000 (UTC) Received: from maggie.brq.redhat.com (unknown [10.43.3.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1C9EA492C2D for ; Tue, 13 Feb 2024 16:16:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: TBzmYK2EPr6OlMU1XCyLlQ-1 From: Michal Privoznik To: devel@lists.libvirt.org Subject: [PATCH 3/4] virsecretobj: Encrypt/decrypt secrets using TPM Date: Tue, 13 Feb 2024 17:16:07 +0100 Message-ID: <0d2ae03a75d98a3784ca2152ac6806bbba5481ff.1707840643.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: ZBU4UFVEHP7QQJYX7SBT3WDQGBOF2I6D X-Message-ID-Hash: ZBU4UFVEHP7QQJYX7SBT3WDQGBOF2I6D X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8"; x-default="true" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1707841436113100001 If user requests their virSecret value to be encrypted using hosts' TPM we can now honour such request as we have all the APIs ready. The value is still stored in a file (obj->base64File) but because it was encrypted by TPM it's not readable (even though it's still base64 encoded). And since we can detect usability of host's TPM, let's do that when a virSecret is defined and TPM is requested. This avoids unpleasant surprises later on. Resolves: https://issues.redhat.com/browse/RHEL-7125 Signed-off-by: Michal Privoznik --- src/conf/virsecretobj.c | 32 +++++++++++++++++++++++++++++--- src/secret/secret_driver.c | 7 +++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c index 455798d414..b77d69649c 100644 --- a/src/conf/virsecretobj.c +++ b/src/conf/virsecretobj.c @@ -24,12 +24,13 @@ #include =20 #include "datatypes.h" -#include "virsecretobj.h" #include "viralloc.h" #include "virerror.h" #include "virfile.h" #include "virhash.h" #include "virlog.h" +#include "virsecret.h" +#include "virsecretobj.h" #include "virstring.h" =20 #define VIR_FROM_THIS VIR_FROM_SECRET @@ -689,7 +690,19 @@ virSecretObjSaveData(virSecretObj *obj) if (!obj->value) return 0; =20 - base64 =3D g_base64_encode(obj->value, obj->value_size); + if (obj->def->tpm =3D=3D VIR_TRISTATE_BOOL_YES) { + char uuidStr[VIR_UUID_STRING_BUFLEN] =3D { 0 }; + + virUUIDFormat(obj->def->uuid, uuidStr); + + if (virSecretTPMEncrypt(uuidStr, + obj->value, obj->value_size, + &base64) < 0) { + return -1; + } + } else { + base64 =3D g_base64_encode(obj->value, obj->value_size); + } =20 if (virFileRewriteStr(obj->base64File, S_IRUSR | S_IWUSR, base64) < 0) return -1; @@ -847,7 +860,20 @@ virSecretLoadValue(virSecretObj *obj) =20 VIR_FORCE_CLOSE(fd); =20 - obj->value =3D g_base64_decode(contents, &obj->value_size); + if (obj->def->tpm =3D=3D VIR_TRISTATE_BOOL_YES) { + char uuidStr[VIR_UUID_STRING_BUFLEN] =3D { 0 }; + + virUUIDFormat(obj->def->uuid, uuidStr); + + if (virSecretTPMDecrypt(uuidStr, + contents, + &obj->value, + &obj->value_size) < 0) { + goto cleanup; + } + } else { + obj->value =3D g_base64_decode(contents, &obj->value_size); + } =20 ret =3D 0; =20 diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index c7bd65b4e9..116d645243 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -234,6 +234,13 @@ secretDefineXML(virConnectPtr conn, if (virSecretDefineXMLEnsureACL(conn, def) < 0) goto cleanup; =20 + if (def->tpm =3D=3D VIR_TRISTATE_BOOL_YES && + virSecretTPMAvailable() !=3D 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TPM is unavailable or unusable on this host")); + goto cleanup; + } + if (!(obj =3D virSecretObjListAdd(driver->secrets, &def, driver->configDir, &backup))) goto cleanup; --=20 2.43.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org From nobody Thu May 9 18:03:01 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1707841502325774.0036963200741; Tue, 13 Feb 2024 08:25:02 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id 46A2E1A90; Tue, 13 Feb 2024 11:25:01 -0500 (EST) Received: from lists.libvirt.org.85.43.8.in-addr.arpa (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id BE9021A03; Tue, 13 Feb 2024 11:16:51 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id B5E5119C5; Tue, 13 Feb 2024 11:16:15 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 35BC819C2 for ; Tue, 13 Feb 2024 11:16:15 -0500 (EST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-575-yfaX9pt5POSHMHgShgl4IQ-1; Tue, 13 Feb 2024 11:16:13 -0500 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0D6CB86306D for ; Tue, 13 Feb 2024 16:16:13 +0000 (UTC) Received: from maggie.brq.redhat.com (unknown [10.43.3.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id A95E9492C2D for ; Tue, 13 Feb 2024 16:16:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 X-MC-Unique: yfaX9pt5POSHMHgShgl4IQ-1 From: Michal Privoznik To: devel@lists.libvirt.org Subject: [PATCH 4/4] NEWS: Document new virSecret TPM feature Date: Tue, 13 Feb 2024 17:16:08 +0100 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Message-ID-Hash: 64C6IZZZYO2NFIWBTYNGWPVBRPKTSVCI X-Message-ID-Hash: 64C6IZZZYO2NFIWBTYNGWPVBRPKTSVCI X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8"; x-default="true" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1707841504306100001 Signed-off-by: Michal Privoznik --- NEWS.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 15b0da31b6..9c0e4b4b65 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -30,6 +30,12 @@ v10.1.0 (unreleased) to resolve names of the connected guests using the name server started for this network. =20 + * virsecretobj: Encrypt/decrypt secrets using TPM + + When defining new ```` user can set ``tpm=3D'yes'`` which the= n makes + libvirt encrypt/decrypt the secret value using host's TPM before store= d on + a disk. + * **Improvements** =20 * **Bug fixes** --=20 2.43.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org