blob: 2549536bac97ae44f684c223c84cffacb39c5111 [file] [log] [blame]
==============================
KERNEL MODULE SIGNING FACILITY
==============================
The module signing facility applies cryptographic signature checking to modules
on module load, checking the signature against a ring of public keys compiled
into the kernel. GPG is used to do the cryptographic work and determines the
format of the signature and key data. The facility uses GPG's MPI library to
handle the huge numbers involved.
The signature checker in the kernel is capable of handling multiple keys of
either DSA or RSA type, and can support any of MD5, RIPE-MD-160, SHA-1,
SHA-224, SHA-256, SHA-384 and SHA-512 hashes - PROVIDED(!) the requisite
algorithms are compiled into the kernel.
(!) NOTE: Modules may only be verified initially with algorithms compiled into
the kernel. Further algorithm modules may be loaded and used - but these must
first pass a verification step using already loaded/compiled-in algorithms.
=====================
SUPPLYING PUBLIC KEYS
=====================
A set of public keys must be supplied at kernel image build time. This is done
by taking a GPG public key file and placing it in the base of the kernel
directory in a file called modsign.pub.
For example, a throwaway key could be generated automatically by something like
the following:
cat >genkey <<EOF
%pubring modsign.pub
%secring modsign.sec
Key-Type: RSA
Key-Length: 4096
Name-Real: A. N. Other
Name-Comment: Kernel Module GPG key
%commit
EOF
gpg --homedir . --batch --gen-key genkey
The above generates fresh keys using /dev/random. If there's insufficient data
in /dev/random, more can be provided using the rngd program if there's a
hardware random number generator available.
Note that no GPG password is used in the above scriptlet.
The modsign.pub file is compiled into the kernel directly by the assembler by
means of an ".incbin" directive in kernel/modsign-pubkey.c.
Once the kernel is running, the keys are visible to root as kernel crypto keys
in /proc/keys in a keyring called .module_sign:
335ab517 I----- 1 perm 1f030000 0 0 keyring .module_sign: 2/4
38d7d169 I----- 1 perm 3f010000 0 0 crypto modsign.0: rsa 57532ca5 []
195fa736 I----- 1 perm 3f010000 0 0 crypto modsign.1: dsa 5acc2142 []
This keyring can be listed with the keyctl program. See:
Documentation/security/keys-crypto.txt
for more information of crypto keys.
============================
SELECTING THE HASH ALGORITHM
============================
The hash algorithm to be used is selected by a multiple choice configuration
item that enables one of the following variables:
CONFIG_SIG_SHA1
CONFIG_SIG_SHA224
CONFIG_SIG_SHA256
CONFIG_SIG_SHA384
CONFIG_SIG_SHA512
These cause an appropriate "--digest-algo=" parameter to be passed to gpg when
signing a module and force the appropriate hash algorithm to be compiled
directly into the kernel rather than being built as a module.
==============
MODULE SIGNING
==============
Modules will then be signed automatically. The kernel make command line can
include the following options:
(*) MODSECKEY=<secret-key-ring-path>
This indicates the whereabouts of the GPG keyring that is the source of
the secret key to be used. The default is "./modsign.sec".
(*) MODPUBKEY=<public-key-ring-path>
This indicates the whereabouts of the GPG keyring that is the source of
the public key to be used. The default is "./modsign.pub".
(*) MODKEYNAME=<key-name>
The name of the key pair to be used from the aforementioned keyrings.
This defaults to being unset, thus leaving the choice of default key to
gpg.
(*) KEYFLAGS="gpg-options"
Override the complete gpg command line, including the preceding three
options. The default options supplied to gpg are:
--no-default-keyring
--secret-keyring $(MODSECKEY)
--keyring $(MODPUBKEY)
--no-default-keyring
--homedir .
--no-options
--no-auto-check-trustdb
--no-permission-warning
--digest-algo=<hash-algorithm>
with:
--default-key $(MODKEYNAME)
being added if requested.
The resulting module.ko file will be the signed module.
============================
SIGNED MODULES AND STRIPPING
============================
The module signature is just appended to the module binary with a magic number
at the end of file, a couple of fixed-size lengths prior to that and the
signature prior to that.
WARNING! Signed modules are BRITTLE as the signature is outside of the defined
ELF container. Thus they MAY NOT be stripped once the signature is computed
and attached, lest the signature be discarded or the payload be modified. Note
that the entire module is the signed payload, including all the debug
information present at the time of signing so it must still be present when the
signature is checked.
As the module may need to be included in a ramdisk image of limited capacity,
modules are maximally stripped prior to signing by the build process.
Note that if FIPS mode is engaged, a module for which the signature does not
match the payload will panic the box.
======================
LOADING SIGNED MODULES
======================
Modules are loaded with insmod, exactly as for unsigned modules. The signature
checker will check at the end of the file for the signature marker and apply
signature checking if found.
=========================================
NON-VALID SIGNATURES AND UNSIGNED MODULES
=========================================
If CONFIG_MODULE_SIG_FORCE is enabled or "enforcemodulesig=1" is supplied on
the kernel command line, the kernel will _only_ load validly signed modules
for which it has a public key. Otherwise, it will also load modules that are
unsigned. Any module for which the kernel has a key, but which proves to have
a signature mismatch will not be permitted to load (returning EKEYREJECTED).
This table indicates the behaviours of the various situations:
MODULE STATE PERMISSIVE MODE ENFORCING MODE
======================================= =============== ===============
Unsigned Ok EKEYREJECTED
Signed, no public key Ok ENOKEY
Validly signed, public key Ok Ok
Invalidly signed, public key EKEYREJECTED EKEYREJECTED
Validly signed, expired key EKEYEXPIRED EKEYEXPIRED
Signed, hash algorithm unavailable ENOPKG ENOPKG
Corrupt signature EBADMSG EBADMSG