Discussion:
Import BearSSL ? (Adding verification to loader)
Simon J. Gerraty
2017-08-30 21:55:48 UTC
Permalink
Hi,

Background:

I've been adding what amounts to a mini "verified exec" to the freebsd
loader for use in Junos.

What this means is that the loader verifies the kernel and all the
modules before loading them, and can reject anything for which a
registered fingerprint (eg. sha1 hash) does not match.

This work is probably mainly of interest to folk doing emeded devices
or security appliances etc and can be seen as closing the gap between
the secure BIOS (which verifies initial loader - grub? whatever)
and mac_veriexec which we use in the kernel to control what can run in
userland.

The boot process on Junos is much more complicated - but also more
flexible than stock FreeBSD.
We potentially load lots of "loader.conf" snippets from different
packages which contribute modules that need to be pre-loaded.

Of particular interest, we always provide the kernel with an md_image
for initial rootfs, which means the loader can verify the kernel and
everything it uses before mac_veriexec is initialized.
This obviates the need to touch the kernel at all.

For efficiency and flexibility of signing, we use signed 'manifest'
files to carry the trusted fingerprints.

These manifest files are signed using RSA or ECDSA and an accompanying
X.509 certificate chain, allows one to verify the public key was issued
by a trusted entity.
This approach has proven useful for more than a decade, and allowing the
loader to do the same, was an obvious choice for us.

Which brings me to BearSSL (www.BearSSL.org)
This is a very small library designed to work in embedded environments.
The author gave a talk about it at BSDCan earlier this year
and it is just what I've been looking for for this project.

All the code to do signature verification, fingerprint matching etc,
in fact the entire mini-veriexec for the loader adds only about 80K.
Last I looked at trying to achieve the same using OpenSSL - I gave up at
6M ;-)

The question is what to do - for upstreaming any of this.
Assuming of course anyone is interested in this functionality.

The changes to the loader itself are trivial.
Most of the code is in libve (naming stuff is hard) which handles
fingerprint loading, lookup and of course verifying signatures using
code from; libbearssl - which is just a reachover build of BearSSL.

I have it setup such that BearSSL need not be part of the tree at all so
there is no burning need to import it; lib/libbearssl will simply not
build if ${BEARSSL} isn't defined and pointing to a BearSSL tree.

From an internal paper-work point-of-view, contrib/bearssl is attractive
to me ;-), but it could just as easily be in ports no where at all.

If it were in contrib, then it would be feasible to leverage it for
other uses in the loader that currently use libmd etc for hashing.

Discuss ?

Thanks
--sjg
Ian Lepore
2017-08-30 22:43:03 UTC
Permalink
Post by Simon J. Gerraty
Hi,
I've been adding what amounts to a mini "verified exec" to the freebsd
loader for use in Junos.
What this means is that the loader verifies the kernel and all the
modules before loading them, and can reject anything for which a
registered fingerprint (eg. sha1 hash) does not match.
[...]
Post by Simon J. Gerraty
The question is what to do - for upstreaming any of this.
Assuming of course anyone is interested in this functionality.
The changes to the loader itself are trivial.
Most of the code is in libve (naming stuff is hard) which handles
fingerprint loading, lookup and of course verifying signatures using
code from; libbearssl - which is just a reachover build of BearSSL.
I have it setup such that BearSSL need not be part of the tree at all so
there is no burning need to import it; lib/libbearssl will simply not
build if ${BEARSSL} isn't defined and pointing to a BearSSL tree.
From an internal paper-work point-of-view, contrib/bearssl is attractive
to me ;-), but it could just as easily be in ports no where at all.
If it were in contrib, then it would be feasible to leverage it for
other uses in the loader that currently use libmd etc for hashing.
Discuss ?
Thanks
--sjg
We need this exact feature (verification of kernel and modules) for an
upcoming product at work.  Including the library code in contrib
certainly sounds attractive to me, too.

I wouldn't be surprised if interest in this goes beyond those of us
building embedded appliances.

-- Ian
Daniel Eischen
2017-08-31 01:21:20 UTC
Permalink
Post by Ian Lepore
Post by Simon J. Gerraty
Hi,
I've been adding what amounts to a mini "verified exec" to the freebsd
loader for use in Junos.
What this means is that the loader verifies the kernel and all the
modules before loading them, and can reject anything for which a
registered fingerprint (eg. sha1 hash) does not match.
[ ... ]
Post by Ian Lepore
We need this exact feature (verification of kernel and modules) for an
upcoming product at work.  Including the library code in contrib
certainly sounds attractive to me, too.
I wouldn't be surprised if interest in this goes beyond those of us
building embedded appliances.
Indeed, why couldn't it be enabled by default for FreeBSD.org
packaged distribs? Or am I jumping the gun by a few years?
--
DE
Jov
2017-08-31 01:55:16 UTC
Permalink
+1
I use zfs+geli encrypted root for several VPS,as the bootpool is not
encrypted, I am always worried that someone may replace my kernel or kernel
module.(I know 11.x support full disk encrypt without bootpool but an
upgrade is not a choice now).

Jov
Post by Daniel Eischen
Post by Daniel Eischen
Post by Simon J. Gerraty
Hi,
I've been adding what amounts to a mini "verified exec" to the freebsd
loader for use in Junos.
What this means is that the loader verifies the kernel and all the
modules before loading them, and can reject anything for which a
registered fingerprint (eg. sha1 hash) does not match.
[ ... ]
We need this exact feature (verification of kernel and modules) for an
upcoming product at work. Including the library code in contrib
certainly sounds attractive to me, too.
I wouldn't be surprised if interest in this goes beyond those of us
building embedded appliances.
Indeed, why couldn't it be enabled by default for FreeBSD.org
packaged distribs? Or am I jumping the gun by a few years?
--
DE
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
Simon J. Gerraty
2017-08-31 03:40:50 UTC
Permalink
Post by Daniel Eischen
Post by Ian Lepore
Post by Simon J. Gerraty
I've been adding what amounts to a mini "verified exec" to the freebsd
loader for use in Junos.
What this means is that the loader verifies the kernel and all the
modules before loading them, and can reject anything for which a
registered fingerprint (eg. sha1 hash) does not match.
[ ... ]
Post by Ian Lepore
We need this exact feature (verification of kernel and modules) for an
upcoming product at work.  Including the library code in contrib
certainly sounds attractive to me, too.
I wouldn't be surprised if interest in this goes beyond those of us
building embedded appliances.
Indeed, why couldn't it be enabled by default for FreeBSD.org
packaged distribs? Or am I jumping the gun by a few years?
The problem with that, boils down to key management.

As an embeded device vendor we totally controll the "trust anchors"
and the keys used to sign things.

And absent the signing, this is all pretty pointless.

My loader for example has 3 Juniper root CA certs in its trust store,
which it can use to verify any signature we have generated
over the last 10+ years.

But it will not accept anything signed by anyone else.
That's perfect for an embedded device, not not exactly useful for a
stock system.

That's why I said this is all mostly likely of interest to embedded
vendors - since the generic case is much harder ;-)

Now, there is absolutely nothing to stop anyone/everyone doing as we
did, and setting up their own X.509 hierarchy, and the signing server we
use (freely available from crufty.net) helps a lot with keeping private
keys private even in a company with 1000's of people signing stuff.

And perhaps FreeBSD.org could sign releases with their own keys.
But if you want to build your own modules you need a way to sign them
such that your loader will accept them.

For something like the loader, an embedded trust-store is a must IMO.
But there's no way you could classify this as a zero effort thing.

Still, with all that said, I currently have the loader defaulting to a
"best effort" mode - where it will attempt to verify everything, but
won't get upset if there is no fingerprint for some file - it will tell
you (unless it was loader.conf - which is more or less expected to be
mutable), though it will not accept a fingerprint miss-match.
This lets me experiment with various platforms etc without bricking lots
of boxes (makes the test folk unhappy).
So you can boot using a verifying loader without everything
signed just fine.

The behavior is of course tunable from "off", to "strict".

--sjg

Loading...