Discussion:
Trust system write-up
Eric McCorkle
2017-10-22 22:14:40 UTC
Permalink
Hello everyone,

The following is a write-up of my current design for a public-key trust
system:

https://www.metricspace.net/files/freebsd_trust.pdf

Some of you are certainly familiar with some or all of this;
I've discussed parts of it before on -hackers and -security, and I
discussed it in greater detail in BoF sessions at vBSDCon. It seems
things are heating up in this direction, so I'd like to get this out
there and get discussion and feedback.

I plan on undertaking work on this in the very near future, especially
since the commit-train for GELI EFI is ready to arrive in HEAD.

A bit about the format: this is sort of the "meat" of what I hope will
be a paper some day, but it's still an initial draft. Moreover, it
talks about things I'm planning as if they exist, mainly because I don't
want to have to go back and rewrite everything in the future. In
reality, most of what I talk about is just a proposal at this point,
with a few bits being implemented as a PoC here and there.

Please read and consider the designs I've proposed. I welcome any
feedback and suggestions. I'll give it a week minimum from today before
I resume any work on this stuff.


Note: Apologies for the external link; I had originally included this as
an attachment, but it was too large.
Shawn Webb
2017-10-22 22:31:33 UTC
Permalink
Post by Eric McCorkle
Hello everyone,
The following is a write-up of my current design for a public-key trust
https://www.metricspace.net/files/freebsd_trust.pdf
Some of you are certainly familiar with some or all of this;
I've discussed parts of it before on -hackers and -security, and I
discussed it in greater detail in BoF sessions at vBSDCon. It seems
things are heating up in this direction, so I'd like to get this out
there and get discussion and feedback.
I plan on undertaking work on this in the very near future, especially
since the commit-train for GELI EFI is ready to arrive in HEAD.
A bit about the format: this is sort of the "meat" of what I hope will
be a paper some day, but it's still an initial draft. Moreover, it
talks about things I'm planning as if they exist, mainly because I don't
want to have to go back and rewrite everything in the future. In
reality, most of what I talk about is just a proposal at this point,
with a few bits being implemented as a PoC here and there.
Please read and consider the designs I've proposed. I welcome any
feedback and suggestions. I'll give it a week minimum from today before
I resume any work on this stuff.
Hey Eric,

Thank you so much for working on this. I do have a few questions.

I'm curious about the rational behind not requiring expiration of
trusted root key material.

Can jails contain a different trust chain than the host?

Thanks,
--
Shawn Webb
Cofounder and Security Engineer
HardenedBSD

GPG Key ID: 0x6A84658F52456EEE
GPG Key Fingerprint: 2ABA B6BD EF6A F486 BE89 3D9E 6A84 658F 5245 6EEE
Eric McCorkle
2017-10-22 23:18:39 UTC
Permalink
Post by Shawn Webb
Hey Eric,
Thank you so much for working on this. I do have a few questions.
I'm curious about the rational behind not requiring expiration of
trusted root key material.
So, I'd say consider most of this written in pencil at this point (minus
the signed ELF extension; I think that's a particularly good point in
design space).

My thinking on root keys is that there really ought to only be one for a
given system, but I'm not so convinced of that that I'd bake it into the
spec. Certainly, though, you need at least one good root key to stay
operational. If you have expiring root keys, you get into all sorts of
nasty cases where your last root key expires, forcing the system down,
or a system can't be booted because its root keys all expired. And
expiring root keys + can't add more root keys means every system
effectively has a countdown to running out of root keys.

I didn't mention it, but I could see provisions for adding/revoking root
keys that hook into some sort of deeper hardware mechanism, say TPMs. I
think that's out-of-scope for now, but it's worth thinking about.
Perhaps expiring root keys could be added along with a mechanism like this.
Post by Shawn Webb
Can jails contain a different trust chain than the host?
I hadn't really folded jails into this yet, but I'd say that's a
definite requirement. It kind of kills the whole virtualization
capability of jails if you can't do that.

I'd say you'd probably want jails to have the option to inherit their
parent's trust DB, as well as establish their own root keys.
Eric McCorkle
2017-10-22 23:21:09 UTC
Permalink
Accidentally replied to -arch only, re-replying to all lists
Post by Shawn Webb
I'm curious about the rational behind not requiring expiration of
trusted root key material.
So, I'd say consider most of this written in pencil at this point (minus
the signed ELF extension; I think that's a particularly good point in
design space).

My thinking on root keys is that there really ought to only be one for a
given system, but I'm not so convinced of that that I'd bake it into the
spec. Certainly, though, you need at least one good root key to stay
operational. If you have expiring root keys, you get into all sorts of
nasty cases where your last root key expires, forcing the system down,
or a system can't be booted because its root keys all expired. And
expiring root keys + can't add more root keys means every system
effectively has a countdown to running out of root keys.

I didn't mention it, but I could see provisions for adding/revoking root
keys that hook into some sort of deeper hardware mechanism, say TPMs. I
think that's out-of-scope for now, but it's worth thinking about.
Perhaps expiring root keys could be added along with a mechanism like this.
Post by Shawn Webb
Can jails contain a different trust chain than the host?
I hadn't really folded jails into this yet, but I'd say that's a
definite requirement. It kind of kills the whole virtualization
capability of jails if you can't do that.

I'd say you'd probably want jails to have the option to inherit their
parent's trust DB, as well as establish their own root keys.
Romain Tartière
2017-10-23 07:11:20 UTC
Permalink
Hello Eric,
Post by Eric McCorkle
The following is a write-up of my current design for a public-key trust
https://www.metricspace.net/files/freebsd_trust.pdf
Two minor things while reading:
1. p2: from a end-user perspective, `trustctl` expects DER encoded
certificates and CRL; while `certs` and `rootcerts` outputs PEM
encoded certificates
 So the formats are not the same, and maybe
consistency would be advisable here;
2. p3: 'the preferred configuration' is said to be the most used one,
but as described it only includes a single crt+key and does not look
suitable for distributing upgrades with freebsd-update(8).
Unless I missed something, I guess it's just the way it is described
that needs disambiguation:
- "local nodes" are basically what is described as "Preferred
configuration", and have a single key+crt.
So these nodes can only run the code they signed.
- "high-security institutions" are kept as it, that is a single crt;
So these nodes can only run code signed by the institution.

Hybrid systems can be built by having more than one root node:
- "preferred configuration" have a local key+crt (as an local node)
AND the FreeBSD's project crt.
So these nodes can run FreeBSD's code and their own code.
- "standard FreeBSD images" as described have the FreeBSD's project
crt. When installing, they generates a local key+crt and add them
with the FreeBSD crt to the new system's trust store. So these
images have the "high-security institutions" scheme, and install
systems in the "preferred configuration" scheme.

Thanks!
Romain
--
Romain TartiÚre <***@FreeBSD.org> http://people.FreeBSD.org/~romain/
pgp: 8234 9A78 E7C0 B807 0B59 80FF BA4D 1D95 5112 336F (ID: 0x5112336F)
(plain text =non-HTML= PGP/GPG encrypted/signed e-mail much appreciated)
Eric McCorkle
2017-10-23 11:56:33 UTC
Permalink
Post by Romain Tartière
Hello Eric,
Post by Eric McCorkle
The following is a write-up of my current design for a public-key trust
https://www.metricspace.net/files/freebsd_trust.pdf
1. p2: from a end-user perspective, `trustctl` expects DER encoded
certificates and CRL; while `certs` and `rootcerts` outputs PEM
encoded certificates… So the formats are not the same, and maybe
consistency would be advisable here;
There's a reason for that. The binary DER encoding is very easy to
parse, and is far less likely to end up with vulnerabilities. Prior to
learning about the discussion surrounding BearSSL, I had been working on
a minimal PKI implementation which only parsed binary DER because it
confers a number of advantages. Each element has a length, so it's easy
to detect malicious or bad data and avoid overruns. Also, you can
easily skip over data you don't need (such as the complex distinguished
name structures), and since it's a distinguished encoding, you can treat
any element as an opaque byte pointer for comparison purposes. All this
closes off a number of attack vectors.

PEM encoding is what applications use, and it's much easier to generate
than to parse. Generating it is straightforward if you have the
DER-encoded data lying around, whereas parsing introduces a number of
possible errors.
Post by Romain Tartière
2. p3: 'the preferred configuration' is said to be the most used one,
but as described it only includes a single crt+key and does not look
suitable for distributing upgrades with freebsd-update(8).
Unless I missed something, I guess it's just the way it is described
The idea is that you'd sign FreeBSD's vendor certificate with the local
system key and add this to your intermediate certificates that get
loaded at boot time.

The installer would probably generate a local keypair, install it as a
root trust certificate, then sign the FreeBSD vendor certificate and
install it as an intermediate trust certificate. This would be enough
to get an initial system up and running. Users that don't want to trust
the FreeBSD cert could then do a buildworld and delete the signed
FreeBSD cert from the intermediate certificate store.
Post by Romain Tartière
- "preferred configuration" have a local key+crt (as an local node)
AND the FreeBSD's project crt.
So these nodes can run FreeBSD's code and their own code.
- "standard FreeBSD images" as described have the FreeBSD's project
crt. When installing, they generates a local key+crt and add them
with the FreeBSD crt to the new system's trust store. So these
images have the "high-security institutions" scheme, and install
systems in the "preferred configuration" scheme.
That is also an option; however, I prefer the configuration where only
the local system key is a root and everything else is an intermediate,
as each root key represents a source of trust that is hard to revoke
(you have to power-cycle). It's almost always better to have a single
root, and make everything else an intermediate, though I'm not sure
enough of that to bake it into the specification.
Simon J. Gerraty
2017-10-23 16:44:34 UTC
Permalink
Post by Eric McCorkle
That is also an option; however, I prefer the configuration where only
the local system key is a root and everything else is an intermediate,
as each root key represents a source of trust that is hard to revoke
(you have to power-cycle). It's almost always better to have a single
root, and make everything else an intermediate, though I'm not sure
enough of that to bake it into the specification.
While we as an embedded vendor might not necessarily want to support any
local signing ability - or to be able to limit the scope of any such
ability, there should be no reason you cannot allow a FreeBSD.org root
cert to be honored in parallel with local root. This should allow
updating system with both locally build s/w and pre-built packages from
FreeBSD.

FWIW when designing the trust model for Junos, preventing any local
control of trust store was an explicit goal.
With the advent of secure boot and TPM's, there is potentially scope to
allow for mixed control.

Please have a look at stevek's mac_veriexec patches in phabricator.
The verified exec model easily allows for "signing" any sort of file,
not just ELF binaries or needing to use special "attached" signature
formats. Thus it allows adding "signing" with minimal impact to most of
the system. This could probably work well in conjunction with your
trust database.

And of course my loader mods follow the same model, so signing
loader.conf, modules etc is all simple with minimal impact to loader
itself.

--sjg
Eric McCorkle
2017-10-23 22:41:29 UTC
Permalink
Post by Simon J. Gerraty
Post by Eric McCorkle
That is also an option; however, I prefer the configuration where only
the local system key is a root and everything else is an intermediate,
as each root key represents a source of trust that is hard to revoke
(you have to power-cycle). It's almost always better to have a single
root, and make everything else an intermediate, though I'm not sure
enough of that to bake it into the specification.
While we as an embedded vendor might not necessarily want to support any
local signing ability - or to be able to limit the scope of any such
ability, there should be no reason you cannot allow a FreeBSD.org root
cert to be honored in parallel with local root. This should allow
updating system with both locally build s/w and pre-built packages from
FreeBSD.
You could do that. You can have as many root certs as you'd like. The
rationale behind the "preferred" configuration is that it's simpler
(fewer attack vectors) and it takes a stance that users should have
exclusive control over their own machine. But nothing stops you from
installing any number of vendor certs as roots.
Post by Simon J. Gerraty
FWIW when designing the trust model for Junos, preventing any local
control of trust store was an explicit goal.
With the advent of secure boot and TPM's, there is potentially scope to
allow for mixed control.
That sounds similar to the high-security setup I described.
Post by Simon J. Gerraty
Please have a look at stevek's mac_veriexec patches in phabricator.
The verified exec model easily allows for "signing" any sort of file,
not just ELF binaries or needing to use special "attached" signature
formats. Thus it allows adding "signing" with minimal impact to most of
the system. This could probably work well in conjunction with your
trust database.
And of course my loader mods follow the same model, so signing
loader.conf, modules etc is all simple with minimal impact to loader
itself.
I've seen that work. The NetBSD veriexec stuff is of interest. I don't
really see it as a "competing" approach, more of a closely-related
security mechanism. I don't see any reason why both mechanisms couldn't
coexist, and there's probably some sort of beneficial interaction
between the two. I could see, for example, veriexec being used to
protect specific files from tampering, with the MACs themselves being
provided by a signed file.

I'm a bit less enthusiastic about veriexec in the loader. The problem
there is it requires an update to the loader every single time you build
a new kernel, whereas the public key approach only needs updating if you
change root keys. (That's really the key difference: veriexec is an
anti-tampering mechanism, where the trust system I've described is a
trust-delegation mechanism).
Simon J. Gerraty
2017-10-23 23:15:20 UTC
Permalink
Post by Eric McCorkle
I'm a bit less enthusiastic about veriexec in the loader. The problem
there is it requires an update to the loader every single time you build
a new kernel, whereas the public key approach only needs updating if you
No, that's exactly what you don't need to do.

The whole advantage of the loader changes I've done is the flexibility
of verification. One loader binary can be used to load any Junos
release we've built in the last decade or the next.

The only time we need a new loader binary, is if some code in the loader
needs to change - or a new rootCA needs to be supported.
The root CA is the only key the loader needs to know.

The signed manifests have an associated certificate chain used for
verification - exactly as we do for normal veriexec.
Post by Eric McCorkle
change root keys. (That's really the key difference: veriexec is an
anti-tampering mechanism, where the trust system I've described is a
trust-delegation mechanism).
Take a closer look, the veriexec manifests can convey additional
information to the kernel (not relevant to loader of course), which
we've made use of to allow apps signed by keys given to 3rd parties to
be run given suitable configuration. We can also assign labels to apps
as a side effect of verification - labels that other mac modules can
use.

--sjg
Rozhuk Ivan
2017-10-24 01:09:25 UTC
Permalink
On Mon, 23 Oct 2017 09:44:34 -0700
Post by Simon J. Gerraty
With the advent of secure boot and TPM's, there is potentially scope
to allow for mixed control.
TPM is closed hardware and software: you dont know what inside and how it works.
Secure boot same crap: closed source with many known security holes.
Simon J. Gerraty
2017-10-24 05:36:12 UTC
Permalink
Post by Rozhuk Ivan
On Mon, 23 Oct 2017 09:44:34 -0700
Post by Simon J. Gerraty
With the advent of secure boot and TPM's, there is potentially scope
to allow for mixed control.
TPM is closed hardware and software: you dont know what inside and how it works.
I'm talking about the TPMs we put on our boards - we know what is in
them.
Eric McCorkle
2017-10-24 10:44:12 UTC
Permalink
Post by Rozhuk Ivan
On Mon, 23 Oct 2017 09:44:34 -0700
Post by Simon J. Gerraty
With the advent of secure boot and TPM's, there is potentially scope
to allow for mixed control.
TPM is closed hardware and software: you dont know what inside and how it works.
Secure boot same crap: closed source with many known security holes.
I think it's necessary to support secure boot for commercial vendors and
such. I personally have no interest in Microsoft being able to certify
random programs to boot on my machines, and am much more interested in
things like coreboot.

There are, however, secure boot mechanisms such as the Power
architecture boot that maintain user control, and I'm hoping with the
rise of RISC-V that we'll see trustworthy hardware crypto and TPM-like
devices.

Ian Lepore
2017-10-23 16:14:45 UTC
Permalink
Post by Eric McCorkle
Hello everyone,
The following is a write-up of my current design for a public-key trust
https://www.metricspace.net/files/freebsd_trust.pdf
Some of you are certainly familiar with some or all of this;
I've discussed parts of it before on -hackers and -security, and I
discussed it in greater detail in BoF sessions at vBSDCon.  It seems
things are heating up in this direction, so I'd like to get this out
there and get discussion and feedback.
I plan on undertaking work on this in the very near future, especially
since the commit-train for GELI EFI is ready to arrive in HEAD.
A bit about the format: this is sort of the "meat" of what I hope will
be a paper some day, but it's still an initial draft.  Moreover, it
talks about things I'm planning as if they exist, mainly because I don't
want to have to go back and rewrite everything in the future.  In
reality, most of what I talk about is just a proposal at this point,
with a few bits being implemented as a PoC here and there.
Please read and consider the designs I've proposed.  I welcome any
feedback and suggestions.  I'll give it a week minimum from today before
I resume any work on this stuff.
Note: Apologies for the external link; I had originally included this as
an attachment, but it was too large.
_______________________________________________
Any thoughts on how to validate executables which are not elf binaries,
such as shell scripts, python programs, etc?

-- Ian
Eric McCorkle
2017-10-23 22:28:02 UTC
Permalink
Post by Ian Lepore
Any thoughts on how to validate executables which are not elf binaries,
such as shell scripts, python programs, etc?
I hadn't really thought in depth about it, as my main initial goal is
signed kernel/modules, but I have given it some thought...

Arguably the "right" way to do it would be to have the signing mechanism
be part of the platform. For example, the JVM has conventions for jar
signing. Not clear how this relates to shell scripts though.


An alternative is something like the NetBSD veriexec framework, where
there's MACs for specific files. That stuff is mostly orthogonal to the
public-key approach I'm working on here, but there's possibly some
interplay.
Simon J. Gerraty
2017-10-23 22:53:05 UTC
Permalink
Post by Eric McCorkle
Post by Ian Lepore
Any thoughts on how to validate executables which are not elf binaries,
such as shell scripts, python programs, etc?
I hadn't really thought in depth about it, as my main initial goal is
signed kernel/modules, but I have given it some thought...
An alternative is something like the NetBSD veriexec framework, where
Yes, as previously mentioned the verified exec model deals with this
neatly, and btw is more efficient than signing individual files - as is
needed with ELF signing etc. I think for linux based platforms using IMA we
need to generate 20-30k+ signatures, vs about a dozen for platforms using
verified exec, verification is also more expensive I'm told.
Post by Eric McCorkle
there's MACs for specific files. That stuff is mostly orthogonal to the
public-key approach I'm working on here, but there's possibly some
interplay.
Yes, you use the public key stuff to sign the manifests containing the
blessed fingerprints.
This is what Junos has been doing for more than a decade.

Your "trust" database, might be useful in being able to extend that to
general use.

The trust model we use for Junos is deliberately very restrictive
and thus of most use to embedded vendors.
Eric McCorkle
2017-10-24 00:00:53 UTC
Permalink
Post by Simon J. Gerraty
Post by Eric McCorkle
Post by Ian Lepore
Any thoughts on how to validate executables which are not elf binaries,
such as shell scripts, python programs, etc?
I hadn't really thought in depth about it, as my main initial goal is
signed kernel/modules, but I have given it some thought...
An alternative is something like the NetBSD veriexec framework, where
Yes, as previously mentioned the verified exec model deals with this
neatly, and btw is more efficient than signing individual files - as is
needed with ELF signing etc. I think for linux based platforms using IMA we
need to generate 20-30k+ signatures, vs about a dozen for platforms using
verified exec, verification is also more expensive I'm told.
Hmmm. There's advantages both ways, and I'll probably end up supporting
both, as it's useful to have an in-band mechanism as well (also, I've
already implemented signed ELFs).

However, there is a definite advantage to having one signature for a
huge number of MACs. Moreover, as I mention in the paper, the most
feasible quantum-safe signature scheme at the present is SPHINCS, which
has signatures about 40Kib in size. That's pretty terrible if you're
signing each executable, but if you're signing 20-30k MACs at 16-32
bytes per code plus a path, suddenly a 40Kib signature doesn't look so
bad anymore. It would be pretty great to roll out a trust
infrastructure AND viable quantum-safe signatures.

I could also see a combined scheme, say, where ELF files carry a UUID
which indexes into a MAC manifest.
Loading...