HardenedBSD/lib/libsecureboot
Simon J. Gerraty f616d61ab6 libsecureboot do not report expected unverified files
By default only report unverified files at severity VE_WANT
and above.  This inlcudes *.conf but not *.hints, *.cookie
or *.tgz which get VE_TRY as their severity.

If Verbose is set to 0, then VerifyFlags should default to 0 too.
Thus the combination of

	module_verbose=0
	VE_VEBOSE=0

is sufficient to make the loader almost totally silent.

When verify_prep has to find_manifest and it is verified ok
return VE_NOT_CHECKED to verify_file so that it can skip
repeating verify_fd

Also add better debugging output for is_verified and add_verify_status.

vectx handle compressed modules

When verifying a compressed module (.ko.gz or .ko.bz2)
stat() reports the size as -1 (unknown).
vectx_lseek needs to spot this during closing - and just read until
EOF is hit.

Note: because of the way libsa's open() works, verify_prep will see
the path to be verified as module.ko not module.ko.bz2 etc.  This is
actually ok, because we need a separate module.ko.bz2 entry so that
the package can be verified, and the hash for module.ko is of the
uncompressed file which is what vectx will see.

Re-work local.trust.mk so site.trust.mk need only set
VE_SIGN_URL_LIST (if using the mentioned signing server)

interp.c: restrict interactive input

Apply the same restrictions to interactive input as for
unverified conf and hints files.

Use version.veriexec when LOADER_VERIEXEC is yes

Reviewed by:	kevans
Sponsored by:	Juniper Networks, Inc.
Differential Revision:	https://reviews.freebsd.org/D43810
2024-02-12 14:35:01 -08:00
..
efi
h libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
openpgp lib: Remove ancient SCCS tags. 2023-11-26 22:23:28 -07:00
tests Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
brf.c
libsecureboot-priv.h
local.trust.mk libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
Makefile Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
Makefile.depend Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
Makefile.depend.amd64 Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
Makefile.depend.host Remove $FreeBSD$: one-line sh pattern 2023-08-16 11:55:03 -06:00
Makefile.inc libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
Makefile.libsa.inc libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
pass_manifest.c
readfile.c
README.rst Remove $FreeBSD$: one-line bare tag 2023-08-16 11:55:20 -06:00
vectx.c libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
veopen.c
vepcr.c
verify_file.c libsecureboot do not report expected unverified files 2024-02-12 14:35:01 -08:00
vesigned.c
veta.c
vets.c libsecureboot: be more verbose about validation failures 2023-12-10 15:13:56 -05:00

libsecureboot
*************

This library depends one way or another on verifying digital signatures.
To do that, the necessary trust anchors need to be available.

The simplest (and most attractive for an embedded system) is to
capture them in this library.

The makefile ``local.trust.mk`` is responsible for doing that.
The file provided is just an example and depends on the environment
here at Juniper.

Within Juniper we use signing servers, which apart from signing things
provide access to the necessary trust anchors.
That signing server is freely available - see
http://www.crufty.net/sjg/docs/signing-server.htm

X.509 certificates chains offer a lot of flexibility over time and are
a great solution for an embedded vendor like Juniper or even
FreeBSD.org, but are probably overkill for personal or small site use.

Setting up a CA for this is rather involved so I'll just provide a
link below to suitable tutorial below.

Using OpenPGP is much simpler.


OpenPGP
========

This is very simple to setup and use.

An RSA key pair can be generated with::

	GNUPGHOME=$PWD/.gnupg gpg --openpgp \
	--quick-generate-key --batch --passphrase '' "keyname" RSA

The use of ``GNUPGHOME=$PWD/.gnupg`` just avoids messing with personal
keyrings.
We can list the resulting key::

	GNUPGHOME=$PWD/.gnupg gpg --openpgp --list-keys

	gpg: WARNING: unsafe permissions on homedir
	'/h/sjg/openpgp/.gnupg'
	gpg: Warning: using insecure memory!
	/h/sjg/openpgp/.gnupg/pubring.kbx
	---------------------------------
	pub   rsa2048 2018-03-26 [SC] [expires: 2020-03-25]
	      AB39B111E40DD019E0E7C171ACA72B4719FD2523
	      uid           [ultimate] OpenPGPtest

The ``keyID`` we want later will be the last 8 octets
(``ACA72B4719FD2523``)
This is what we will use for looking up the key.

We can then export the private and public keys::

	GNUPGHOME=$PWD/.gnupg gpg --openpgp \
	--export --armor > ACA72B4719FD2523.pub.asc
	GNUPGHOME=$PWD/.gnupg gpg --openpgp \
	--export-secret-keys --armor > ACA72B4719FD2523.sec.asc

The public key ``ACA72B4719FD2523.pub.asc`` is what we want to
embed in this library.
If you look at the ``ta_asc.h`` target in ``openpgp/Makefile.inc``
we want the trust anchor in a file named ``t*.asc``
eg. ``ta_openpgp.asc``.

The ``ta_asc.h`` target will capture all such ``t*.asc`` into that
header.

Signatures
----------

We expect ascii armored (``.asc``) detached signatures.
Eg. signature for ``manifest`` would be in ``manifest.asc``

We only support version 4 signatures using RSA (the default for ``gpg``).


OpenSSL
========

The basic idea here is to setup a private CA.

There are lots of good tutorials on available on this topic;
just google *setup openssl ca*.
A good example is https://jamielinux.com/docs/openssl-certificate-authority/

All we need for this library is a copy of the PEM encoded root CA
certificate (trust anchor).  This is expected to be in a file named
``t*.pem`` eg. ``ta_rsa.pem``.

The ``ta.h`` target in ``Makefile.inc`` will combine all such
``t*.pem`` files into that header.

Signatures
----------

For Junos we currently use EC DSA signatures with file extension
``.esig`` so the signature for ``manifest`` would be ``manifest.esig``

This was the first signature method we used with the remote signing
servers and it ends up being a signature of a hash.
Ie. client sends a hash which during signing gets hashed again.
So for Junos we define VE_ECDSA_HASH_AGAIN which causes ``verify_ec``
to hash again.

Otherwise our EC DSA and RSA signatures are the default used by
OpenSSL - an original design goal was that a customer could verify our
signatures using nothing but an ``openssl`` binary.


Self tests
==========

If you want the ``loader`` to perform self-test of a given signature
verification method on startup (a must for FIPS 140-2 certification)
you need to provide a suitable file signed by each supported trust
anchor.

These should be stored in files with names that start with ``v`` and
have the same extension as the corresponding trust anchor.
Eg. for ``ta_openpgp.asc`` we use ``vc_openpgp.asc``
and for ``ta_rsa.pem`` we use ``vc_rsa.pem``.

Note for the X.509 case we simply extract the 2nd last certificate
from the relevant chain - which is sure to be a valid certificate
signed by the corresponding trust anchor.

--------------------