[RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node

Stefan Berger posted 6 patches 1 year, 4 months ago
There is a newer version of this series
[RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Stefan Berger 1 year, 4 months ago
Extend the schema for the TPM emulator profile node. Require that
the profile the user provides looks like a JSON map that at least
starts with '{' and ends with '}'.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 src/conf/schemas/basictypes.rng   |  6 ++++++
 src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
index 2931e316b7..06df0fe67e 100644
--- a/src/conf/schemas/basictypes.rng
+++ b/src/conf/schemas/basictypes.rng
@@ -677,4 +677,10 @@
     </element>
   </define>
 
+  <define name="JSONMap">
+    <data type="string">
+      <param name="pattern">\{.*\}</param>
+    </data>
+  </define>
+
 </grammar>
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index efb5f00d77..f80a6afc06 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -5923,6 +5923,7 @@
           <interleave>
             <ref name="tpm-backend-emulator-encryption"/>
             <ref name="tpm-backend-emulator-active-pcr-banks"/>
+            <ref name="tpm-backend-emulator-profile"/>
           </interleave>
           <optional>
             <attribute name="persistent_state">
@@ -6020,6 +6021,22 @@
     </optional>
   </define>
 
+  <define name="tpm-backend-emulator-profile">
+    <optional>
+      <element name="profile">
+        <optional>
+          <attribute name="remove_disabled">
+            <choice>
+              <value>check</value>
+              <value>fips-host</value>
+            </choice>
+          </attribute>
+        </optional>
+        <ref name="JSONMap"/>
+      </element>
+    </optional>
+  </define>
+
   <define name="vsock">
     <element name="vsock">
       <optional>
-- 
2.46.0
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Marc-André Lureau 1 year, 4 months ago
Hi

On Thu, Sep 19, 2024 at 10:05 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>
> Extend the schema for the TPM emulator profile node. Require that
> the profile the user provides looks like a JSON map that at least
> starts with '{' and ends with '}'.
>
> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
>  src/conf/schemas/basictypes.rng   |  6 ++++++
>  src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
> index 2931e316b7..06df0fe67e 100644
> --- a/src/conf/schemas/basictypes.rng
> +++ b/src/conf/schemas/basictypes.rng
> @@ -677,4 +677,10 @@
>      </element>
>    </define>
>
> +  <define name="JSONMap">
> +    <data type="string">
> +      <param name="pattern">\{.*\}</param>
> +    </data>
> +  </define>

It's unfortunate, but I think this should rather be XML and converted
to JSON internally (after all, that's part of what libvirt does with
QEMU configuration, somehow)

if there is a precedent for such mixing of languages, and it's
acceptable I am okay with it too

> +
>  </grammar>
> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
> index efb5f00d77..f80a6afc06 100644
> --- a/src/conf/schemas/domaincommon.rng
> +++ b/src/conf/schemas/domaincommon.rng
> @@ -5923,6 +5923,7 @@
>            <interleave>
>              <ref name="tpm-backend-emulator-encryption"/>
>              <ref name="tpm-backend-emulator-active-pcr-banks"/>
> +            <ref name="tpm-backend-emulator-profile"/>
>            </interleave>
>            <optional>
>              <attribute name="persistent_state">
> @@ -6020,6 +6021,22 @@
>      </optional>
>    </define>
>
> +  <define name="tpm-backend-emulator-profile">
> +    <optional>
> +      <element name="profile">
> +        <optional>
> +          <attribute name="remove_disabled">
> +            <choice>
> +              <value>check</value>
> +              <value>fips-host</value>
> +            </choice>
> +          </attribute>
> +        </optional>
> +        <ref name="JSONMap"/>
> +      </element>
> +    </optional>
> +  </define>
> +
>    <define name="vsock">
>      <element name="vsock">
>        <optional>
> --
> 2.46.0
>
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Peter Krempa 1 year, 4 months ago
On Fri, Sep 20, 2024 at 15:24:03 +0400, Marc-André Lureau wrote:
> Hi
> 
> On Thu, Sep 19, 2024 at 10:05 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
> >
> > Extend the schema for the TPM emulator profile node. Require that
> > the profile the user provides looks like a JSON map that at least
> > starts with '{' and ends with '}'.
> >
> > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > ---
> >  src/conf/schemas/basictypes.rng   |  6 ++++++
> >  src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
> >  2 files changed, 23 insertions(+)
> >
> > diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
> > index 2931e316b7..06df0fe67e 100644
> > --- a/src/conf/schemas/basictypes.rng
> > +++ b/src/conf/schemas/basictypes.rng
> > @@ -677,4 +677,10 @@
> >      </element>
> >    </define>
> >
> > +  <define name="JSONMap">
> > +    <data type="string">
> > +      <param name="pattern">\{.*\}</param>
> > +    </data>
> > +  </define>
> 
> It's unfortunate, but I think this should rather be XML and converted
> to JSON internally (after all, that's part of what libvirt does with
> QEMU configuration, somehow)

Yeah, having arbitrary JSON is weird and also bypasses the philosophy
that libvirt should express in the schema only what we really support
(E.g. no raw arbitrary value passthrough, unless explicitly marked as
without guarantees)

> 
> if there is a precedent for such mixing of languages, and it's
> acceptable I am okay with it too

We don't have anything like that.
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Daniel P. Berrangé 1 year, 4 months ago
On Fri, Sep 20, 2024 at 01:53:41PM +0200, Peter Krempa wrote:
> On Fri, Sep 20, 2024 at 15:24:03 +0400, Marc-André Lureau wrote:
> > Hi
> > 
> > On Thu, Sep 19, 2024 at 10:05 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
> > >
> > > Extend the schema for the TPM emulator profile node. Require that
> > > the profile the user provides looks like a JSON map that at least
> > > starts with '{' and ends with '}'.
> > >
> > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
> > > ---
> > >  src/conf/schemas/basictypes.rng   |  6 ++++++
> > >  src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
> > >  2 files changed, 23 insertions(+)
> > >
> > > diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
> > > index 2931e316b7..06df0fe67e 100644
> > > --- a/src/conf/schemas/basictypes.rng
> > > +++ b/src/conf/schemas/basictypes.rng
> > > @@ -677,4 +677,10 @@
> > >      </element>
> > >    </define>
> > >
> > > +  <define name="JSONMap">
> > > +    <data type="string">
> > > +      <param name="pattern">\{.*\}</param>
> > > +    </data>
> > > +  </define>
> > 
> > It's unfortunate, but I think this should rather be XML and converted
> > to JSON internally (after all, that's part of what libvirt does with
> > QEMU configuration, somehow)
> 
> Yeah, having arbitrary JSON is weird and also bypasses the philosophy
> that libvirt should express in the schema only what we really support
> (E.g. no raw arbitrary value passthrough, unless explicitly marked as
> without guarantees)

IMHO, we should not be defining raw crypto profiles in the XML at
all, whether JSON or not. I don't see profile definitions as being
something that needs to change per-VM definition. This is a case
where there ought to be a set of common profiles defined, and just
referenced by name at the VM configuration level.

IOW swtpm itself is fully configurable which makes sense, but we
don't need to expose this up to the libvirt level.

Instead I think there should be a defined standard for how an distro
package, or host sysadmin, would "drop in" a profile definition to
a well defined directory, where upon we can reference it by name in
libvirt,

eg define two dirs

   /usr/share/swptm/profiles/<name>.json   (for os distro)
   /etc/swptm/profiles/<name>.json         (for local deployment)



With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Stefan Berger 1 year, 4 months ago

On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
> On Fri, Sep 20, 2024 at 01:53:41PM +0200, Peter Krempa wrote:
>> On Fri, Sep 20, 2024 at 15:24:03 +0400, Marc-André Lureau wrote:
>>> Hi
>>>
>>> On Thu, Sep 19, 2024 at 10:05 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>>>
>>>> Extend the schema for the TPM emulator profile node. Require that
>>>> the profile the user provides looks like a JSON map that at least
>>>> starts with '{' and ends with '}'.
>>>>
>>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>>>> ---
>>>>   src/conf/schemas/basictypes.rng   |  6 ++++++
>>>>   src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
>>>>   2 files changed, 23 insertions(+)
>>>>
>>>> diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
>>>> index 2931e316b7..06df0fe67e 100644
>>>> --- a/src/conf/schemas/basictypes.rng
>>>> +++ b/src/conf/schemas/basictypes.rng
>>>> @@ -677,4 +677,10 @@
>>>>       </element>
>>>>     </define>
>>>>
>>>> +  <define name="JSONMap">
>>>> +    <data type="string">
>>>> +      <param name="pattern">\{.*\}</param>
>>>> +    </data>
>>>> +  </define>
>>>
>>> It's unfortunate, but I think this should rather be XML and converted
>>> to JSON internally (after all, that's part of what libvirt does with
>>> QEMU configuration, somehow)
>>
>> Yeah, having arbitrary JSON is weird and also bypasses the philosophy
>> that libvirt should express in the schema only what we really support
>> (E.g. no raw arbitrary value passthrough, unless explicitly marked as
>> without guarantees)
> 
> IMHO, we should not be defining raw crypto profiles in the XML at
> all, whether JSON or not. I don't see profile definitions as being
> something that needs to change per-VM definition. This is a case
> where there ought to be a set of common profiles defined, and just
> referenced by name at the VM configuration level.
> 
> IOW swtpm itself is fully configurable which makes sense, but we
> don't need to expose this up to the libvirt level.
> 


FYI: Currently the following profiles are supported:

swtpm_ioctl --tcp :2322 --info 0x40 | jq
{
   "AvailableProfiles": [
     {
       "Name": "default-v1",
       "StateFormatLevel": 7,
       "Commands": 
"0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197,0x199-0x19c",
       "Algorithms": 
"rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
       "Description": "This profile enables all libtpms v0.10-supported 
commands and algorithms. This profile is compatible with libtpms >= v0.10."
     },
     {
       "Name": "null",
       "StateFormatLevel": 1,
       "Commands": 
"0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197",
       "Algorithms": 
"rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
       "Description": "The profile enables the commands and algorithms 
that were enabled in libtpms v0.9. This profile is automatically used 
when the state does not have a profile, for example when it was created 
by libtpms v0.9 or before. This profile enables compatibility with 
libtpms >= v0.9."
     },
     {
       "Name": "custom",
       "StateFormatLevel": 2,
       "Commands": 
"0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197,0x199-0x19c",
       "Algorithms": 
"rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
       "Description": "This profile allows customization of enabled 
algorithms and commands. This profile requires at least libtpms v0.10."
     }
   ]
}

The null profile is an implicit profile for all libtpms v0.9 instances 
upgrade to later version of libtpms. It is implicit because it is not 
part of the TPM state. It can be passed as '{"Name":"null"}' to a TPM 2 
created with lintpms v0.10 that can then also work with libtpms v0.9.

The default-v1 profile will be applied to any instance that does not 
provide a profile explicitly. A TPM created with it cannot be read by 
libtpms v0.9.

Only the custom profile can be modified but that leaves enough room for 
distros to design a profile except they need to call it 'custom'. They 
can change the rest within the limits of what is allowed to be removed 
and of course what doesn't throw off any potential application (test 
suites?) that may now be missing some TPM functionality.

 > Instead I think there should be a defined standard for how an distro
 > package, or host sysadmin, would "drop in" a profile definition to
 > a well defined directory, where upon we can reference it by name in
 > libvirt,
 >
 > eg define two dirs
 >
 >     /usr/share/swptm/profiles/<name>.json   (for os distro)
 >     /etc/swptm/profiles/<name>.json         (for local deployment)

With the above:

<profile name='null' type='built-in'/>
<profile name='default-v1' type='built-in'/>
<profile name='custom' type='built-in' remove_disabled='check'/>

<profile name='restricted' type='distro'/>    --> name is a filename now
<profile name='test' type='local' remove_disabled='check'/>  --> name is 
a filename now

I suppose the above paths should be part of a config file?

    Stefan

> 
> 
> 
> With regards,
> Daniel
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Daniel P. Berrangé 1 year, 4 months ago
On Fri, Sep 20, 2024 at 10:00:40AM -0400, Stefan Berger wrote:
> 
> 
> On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
> > Instead I think there should be a defined standard for how an distro
> > package, or host sysadmin, would "drop in" a profile definition to
> > a well defined directory, where upon we can reference it by name in
> > libvirt,
> >
> > eg define two dirs
> >
> >     /usr/share/swptm/profiles/<name>.json   (for os distro)
> >     /etc/swptm/profiles/<name>.json         (for local deployment)
> 
> With the above:
> 
> <profile name='null' type='built-in'/>
> <profile name='default-v1' type='built-in'/>
> <profile name='custom' type='built-in' remove_disabled='check'/>
> 
> <profile name='restricted' type='distro'/>    --> name is a filename now
> <profile name='test' type='local' remove_disabled='check'/>  --> name is a
> filename now

Do we really need to express a "type" attribute ? How about if
swtpm itself were to load profiles from the /usr/share/swtpm
and /etc/swtpm directories, so that from a users' POV there
is no distinction between built-in & file defined profiles ?

I guess you want to resolve naming clashes. A couple of options

 - <name>.json in /etc/ overrides <name>.json in /usr/
   which overrides <name> built-in.

 - <name>.json in /etc is ignored if it clashes with <name>.json
   in /usr or built-in 

 - swtpm gives the profile name a prefix itself, based
   on where it came from eg  "system:blah" or "local:blah"
   for /usr/ and /etc respectively.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Stefan Berger 1 year, 4 months ago

On 9/23/24 12:55 PM, Daniel P. Berrangé wrote:
> On Fri, Sep 20, 2024 at 10:00:40AM -0400, Stefan Berger wrote:
>>
>>
>> On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
>>> Instead I think there should be a defined standard for how an distro
>>> package, or host sysadmin, would "drop in" a profile definition to
>>> a well defined directory, where upon we can reference it by name in
>>> libvirt,
>>>
>>> eg define two dirs
>>>
>>>      /usr/share/swptm/profiles/<name>.json   (for os distro)
>>>      /etc/swptm/profiles/<name>.json         (for local deployment)
>>
>> With the above:
>>
>> <profile name='null' type='built-in'/>
>> <profile name='default-v1' type='built-in'/>
>> <profile name='custom' type='built-in' remove_disabled='check'/>
>>
>> <profile name='restricted' type='distro'/>    --> name is a filename now
>> <profile name='test' type='local' remove_disabled='check'/>  --> name is a
>> filename now
> 
> Do we really need to express a "type" attribute ? How about if
> swtpm itself were to load profiles from the /usr/share/swtpm
> and /etc/swtpm directories, so that from a users' POV there
> is no distinction between built-in & file defined profiles ?
> 
> I guess you want to resolve naming clashes. A couple of options
> 
>   - <name>.json in /etc/ overrides <name>.json in /usr/
>     which overrides <name> built-in.
> 

I think this makes it easier for a user to choose from:

<profile builtin="null"/>
<profile builtin="default-v1"/>
<profile builtin=custom" remove_disabled='check'/>
<profile distro='restricted'/>
<profile local='test' remove_disabled='check'/>


>   - <name>.json in /etc is ignored if it clashes with <name>.json
>     in /usr or built-in
> 
>   - swtpm gives the profile name a prefix itself, based
>     on where it came from eg  "system:blah" or "local:blah"
>     for /usr/ and /etc respectively.
> 
> 
> With regards,
> Daniel
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Daniel P. Berrangé 1 year, 4 months ago
On Mon, Sep 23, 2024 at 01:30:50PM -0400, Stefan Berger wrote:
> 
> 
> On 9/23/24 12:55 PM, Daniel P. Berrangé wrote:
> > On Fri, Sep 20, 2024 at 10:00:40AM -0400, Stefan Berger wrote:
> > > 
> > > 
> > > On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
> > > > Instead I think there should be a defined standard for how an distro
> > > > package, or host sysadmin, would "drop in" a profile definition to
> > > > a well defined directory, where upon we can reference it by name in
> > > > libvirt,
> > > > 
> > > > eg define two dirs
> > > > 
> > > >      /usr/share/swptm/profiles/<name>.json   (for os distro)
> > > >      /etc/swptm/profiles/<name>.json         (for local deployment)
> > > 
> > > With the above:
> > > 
> > > <profile name='null' type='built-in'/>
> > > <profile name='default-v1' type='built-in'/>
> > > <profile name='custom' type='built-in' remove_disabled='check'/>
> > > 
> > > <profile name='restricted' type='distro'/>    --> name is a filename now
> > > <profile name='test' type='local' remove_disabled='check'/>  --> name is a
> > > filename now
> > 
> > Do we really need to express a "type" attribute ? How about if
> > swtpm itself were to load profiles from the /usr/share/swtpm
> > and /etc/swtpm directories, so that from a users' POV there
> > is no distinction between built-in & file defined profiles ?
> > 
> > I guess you want to resolve naming clashes. A couple of options
> > 
> >   - <name>.json in /etc/ overrides <name>.json in /usr/
> >     which overrides <name> built-in.
> > 
> 
> I think this makes it easier for a user to choose from:
> 
> <profile builtin="null"/>
> <profile builtin="default-v1"/>
> <profile builtin=custom" remove_disabled='check'/>
> <profile distro='restricted'/>
> <profile local='test' remove_disabled='check'/>

I think that creates unneccessary upgrade drama. Consider that new
swtpm defines a new built-in profile "default-v3", but your current
host does not have "default-v3" as a built-in profile. You should
be able to define that as a local profile or system profile with
the same name, and have an upgrade path to future swtpm which has
it as a built-in profile *without* having to change the XML.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Stefan Berger 1 year, 4 months ago

On 9/24/24 4:35 AM, Daniel P. Berrangé wrote:
> On Mon, Sep 23, 2024 at 01:30:50PM -0400, Stefan Berger wrote:
>>
>>
>> On 9/23/24 12:55 PM, Daniel P. Berrangé wrote:
>>> On Fri, Sep 20, 2024 at 10:00:40AM -0400, Stefan Berger wrote:
>>>>
>>>>
>>>> On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
>>>>> Instead I think there should be a defined standard for how an distro
>>>>> package, or host sysadmin, would "drop in" a profile definition to
>>>>> a well defined directory, where upon we can reference it by name in
>>>>> libvirt,
>>>>>
>>>>> eg define two dirs
>>>>>
>>>>>       /usr/share/swptm/profiles/<name>.json   (for os distro)
>>>>>       /etc/swptm/profiles/<name>.json         (for local deployment)
>>>>
>>>> With the above:
>>>>
>>>> <profile name='null' type='built-in'/>
>>>> <profile name='default-v1' type='built-in'/>
>>>> <profile name='custom' type='built-in' remove_disabled='check'/>
>>>>
>>>> <profile name='restricted' type='distro'/>    --> name is a filename now
>>>> <profile name='test' type='local' remove_disabled='check'/>  --> name is a
>>>> filename now
>>>
>>> Do we really need to express a "type" attribute ? How about if
>>> swtpm itself were to load profiles from the /usr/share/swtpm
>>> and /etc/swtpm directories, so that from a users' POV there
>>> is no distinction between built-in & file defined profiles ?
>>>
>>> I guess you want to resolve naming clashes. A couple of options
>>>
>>>    - <name>.json in /etc/ overrides <name>.json in /usr/
>>>      which overrides <name> built-in.
>>>
>>
>> I think this makes it easier for a user to choose from:
>>
>> <profile builtin="null"/>
>> <profile builtin="default-v1"/>
>> <profile builtin=custom" remove_disabled='check'/>
>> <profile distro='restricted'/>
>> <profile local='test' remove_disabled='check'/>
> 
> I think that creates unneccessary upgrade drama. Consider that new
> swtpm defines a new built-in profile "default-v3", but your current
> host does not have "default-v3" as a built-in profile. You should

Exactly these default-v{1,2,3,...} profiles will all be built into 
libtpms and the latest one will be activated if the user chooses no 
profile when starting swtpm the first time and it creates initial state.

swtpm_setup, which is used to 'manufacture' a TPM, tries to read a 
default profile from its configuration file (/etc/swtpm_setup.conf) and 
set that one if the user didn't provide one on the swtpm_setup command 
line. If nothing is set it's back to the default-v{1,..} profile on 
libtpms level enabling the latest crypto algorithms the TPM 2 supports.

The profile default-v3 would be there because new crypto algorithms etc, 
were added to (future) libtpms v0.12 and they are then enable in this 
profile. If there weren't any new crypto algorithms or other verbs added 
to the profile language, libtpms would still be offering only default-v2 
(from future libtpms v0.11 presumably). So you will need to have 
(future) v0.12 of libtpms to run default-v3. And it won't be possible to 
run this instance on a previous version of libtpms, for this you would 
have to pick an older default-v{1,2} profile that will still be made 
available as built-in's.

Maybe a search order through directories should be supported on the 
swtpm_setup level using its configuration file that is either picked up 
from /etc/swtpm_local.conf or ~/.config/swtpm_setup.conf where one can 
then specify a local and a distro directory (or the distro one hardcoded 
in swtpm_setup?) for profiles to search through.

The tricky part about other than the built-in profiles will be to decide 
which algorithms to disable without upsetting applications. But I agree, 
access to local or distro profiles will be useful along with 
'swtpm_setup --tpm2 --print-profiles' for displaying them. I was going 
to do the directory configuration on the libvirt level...

> be able to define that as a local profile or system profile with
> the same name, and have an upgrade path to future swtpm which has
> it as a built-in profile *without* having to change the XML. >
> 
> With regards,
> Daniel
Re: [RFC PATCH v1 3/6] schema: Extend schema for TPM emulator profile node
Posted by Stefan Berger 1 year, 4 months ago

On 9/20/24 10:00 AM, Stefan Berger wrote:
> 
> 
> On 9/20/24 8:55 AM, Daniel P. Berrangé wrote:
>> On Fri, Sep 20, 2024 at 01:53:41PM +0200, Peter Krempa wrote:
>>> On Fri, Sep 20, 2024 at 15:24:03 +0400, Marc-André Lureau wrote:
>>>> Hi
>>>>
>>>> On Thu, Sep 19, 2024 at 10:05 PM Stefan Berger 
>>>> <stefanb@linux.ibm.com> wrote:
>>>>>
>>>>> Extend the schema for the TPM emulator profile node. Require that
>>>>> the profile the user provides looks like a JSON map that at least
>>>>> starts with '{' and ends with '}'.
>>>>>
>>>>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>>>>> ---
>>>>>   src/conf/schemas/basictypes.rng   |  6 ++++++
>>>>>   src/conf/schemas/domaincommon.rng | 17 +++++++++++++++++
>>>>>   2 files changed, 23 insertions(+)
>>>>>
>>>>> diff --git a/src/conf/schemas/basictypes.rng 
>>>>> b/src/conf/schemas/basictypes.rng
>>>>> index 2931e316b7..06df0fe67e 100644
>>>>> --- a/src/conf/schemas/basictypes.rng
>>>>> +++ b/src/conf/schemas/basictypes.rng
>>>>> @@ -677,4 +677,10 @@
>>>>>       </element>
>>>>>     </define>
>>>>>
>>>>> +  <define name="JSONMap">
>>>>> +    <data type="string">
>>>>> +      <param name="pattern">\{.*\}</param>
>>>>> +    </data>
>>>>> +  </define>
>>>>
>>>> It's unfortunate, but I think this should rather be XML and converted
>>>> to JSON internally (after all, that's part of what libvirt does with
>>>> QEMU configuration, somehow)
>>>
>>> Yeah, having arbitrary JSON is weird and also bypasses the philosophy
>>> that libvirt should express in the schema only what we really support
>>> (E.g. no raw arbitrary value passthrough, unless explicitly marked as
>>> without guarantees)
>>
>> IMHO, we should not be defining raw crypto profiles in the XML at
>> all, whether JSON or not. I don't see profile definitions as being
>> something that needs to change per-VM definition. This is a case
>> where there ought to be a set of common profiles defined, and just
>> referenced by name at the VM configuration level.
>>
>> IOW swtpm itself is fully configurable which makes sense, but we
>> don't need to expose this up to the libvirt level.
>>
> 
> 
> FYI: Currently the following profiles are supported:
> 
> swtpm_ioctl --tcp :2322 --info 0x40 | jq
> {
>    "AvailableProfiles": [
>      {
>        "Name": "default-v1",
>        "StateFormatLevel": 7,
>        "Commands": 
> "0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197,0x199-0x19c",
>        "Algorithms": 
> "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
>        "Description": "This profile enables all libtpms v0.10-supported 
> commands and algorithms. This profile is compatible with libtpms >= v0.10."
>      },
>      {
>        "Name": "null",
>        "StateFormatLevel": 1,
>        "Commands": 
> "0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197",
>        "Algorithms": 
> "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
>        "Description": "The profile enables the commands and algorithms 
> that were enabled in libtpms v0.9. This profile is automatically used 
> when the state does not have a profile, for example when it was created 
> by libtpms v0.9 or before. This profile enables compatibility with 
> libtpms >= v0.9."
>      },
>      {
>        "Name": "custom",
>        "StateFormatLevel": 2,
>        "Commands": 
> "0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197,0x199-0x19c",
>        "Algorithms": 
> "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
>        "Description": "This profile allows customization of enabled 
> algorithms and commands. This profile requires at least libtpms v0.10."
>      }
>    ]
> }
> 
> The null profile is an implicit profile for all libtpms v0.9 instances 
> upgrade to later version of libtpms. It is implicit because it is not 
> part of the TPM state. It can be passed as '{"Name":"null"}' to a TPM 2 
> created with lintpms v0.10 that can then also work with libtpms v0.9.
> 
> The default-v1 profile will be applied to any instance that does not 
> provide a profile explicitly. A TPM created with it cannot be read by 
> libtpms v0.9.
> 
> Only the custom profile can be modified but that leaves enough room for 
> distros to design a profile except they need to call it 'custom'. They 
> can change the rest within the limits of what is allowed to be removed 
> and of course what doesn't throw off any potential application (test 
> suites?) that may now be missing some TPM functionality.
> 
>  > Instead I think there should be a defined standard for how an distro
>  > package, or host sysadmin, would "drop in" a profile definition to
>  > a well defined directory, where upon we can reference it by name in
>  > libvirt,
>  >
>  > eg define two dirs
>  >
>  >     /usr/share/swptm/profiles/<name>.json   (for os distro)
>  >     /etc/swptm/profiles/<name>.json         (for local deployment)
> 
> With the above:
> 
> <profile name='null' type='built-in'/>
> <profile name='default-v1' type='built-in'/>
> <profile name='custom' type='built-in' remove_disabled='check'/>
> 
> <profile name='restricted' type='distro'/>    --> name is a filename now
> <profile name='test' type='local' remove_disabled='check'/>  --> name is 
> a filename now

Better:

<profile builtin="null"/>
<profile builtin="default-v1"/>
<profile builtin=custom" remove_disabled='check'/>
<profile distro='restricted'/>
<profile local='test' remove_disabled='check'/>

> 
> I suppose the above paths should be part of a config file?
> 
>     Stefan
> 
>>
>>
>>
>> With regards,
>> Daniel