162306a36Sopenharmony_ciKernel module signing facility
262306a36Sopenharmony_ci------------------------------
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci.. CONTENTS
562306a36Sopenharmony_ci..
662306a36Sopenharmony_ci.. - Overview.
762306a36Sopenharmony_ci.. - Configuring module signing.
862306a36Sopenharmony_ci.. - Generating signing keys.
962306a36Sopenharmony_ci.. - Public keys in the kernel.
1062306a36Sopenharmony_ci.. - Manually signing modules.
1162306a36Sopenharmony_ci.. - Signed modules and stripping.
1262306a36Sopenharmony_ci.. - Loading signed modules.
1362306a36Sopenharmony_ci.. - Non-valid signatures and unsigned modules.
1462306a36Sopenharmony_ci.. - Administering/protecting the private key.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci========
1862306a36Sopenharmony_ciOverview
1962306a36Sopenharmony_ci========
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciThe kernel module signing facility cryptographically signs modules during
2262306a36Sopenharmony_ciinstallation and then checks the signature upon loading the module.  This
2362306a36Sopenharmony_ciallows increased kernel security by disallowing the loading of unsigned modules
2462306a36Sopenharmony_cior modules signed with an invalid key.  Module signing increases security by
2562306a36Sopenharmony_cimaking it harder to load a malicious module into the kernel.  The module
2662306a36Sopenharmony_cisignature checking is done by the kernel so that it is not necessary to have
2762306a36Sopenharmony_citrusted userspace bits.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciThis facility uses X.509 ITU-T standard certificates to encode the public keys
3062306a36Sopenharmony_ciinvolved.  The signatures are not themselves encoded in any industrial standard
3162306a36Sopenharmony_citype.  The facility currently only supports the RSA public key encryption
3262306a36Sopenharmony_cistandard (though it is pluggable and permits others to be used).  The possible
3362306a36Sopenharmony_cihash algorithms that can be used are SHA-1, SHA-224, SHA-256, SHA-384, and
3462306a36Sopenharmony_ciSHA-512 (the algorithm is selected by data in the signature).
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci==========================
3862306a36Sopenharmony_ciConfiguring module signing
3962306a36Sopenharmony_ci==========================
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciThe module signing facility is enabled by going to the
4262306a36Sopenharmony_ci:menuselection:`Enable Loadable Module Support` section of
4362306a36Sopenharmony_cithe kernel configuration and turning on::
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	CONFIG_MODULE_SIG	"Module signature verification"
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciThis has a number of options available:
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci (1) :menuselection:`Require modules to be validly signed`
5062306a36Sopenharmony_ci     (``CONFIG_MODULE_SIG_FORCE``)
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci     This specifies how the kernel should deal with a module that has a
5362306a36Sopenharmony_ci     signature for which the key is not known or a module that is unsigned.
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci     If this is off (ie. "permissive"), then modules for which the key is not
5662306a36Sopenharmony_ci     available and modules that are unsigned are permitted, but the kernel will
5762306a36Sopenharmony_ci     be marked as being tainted, and the concerned modules will be marked as
5862306a36Sopenharmony_ci     tainted, shown with the character 'E'.
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci     If this is on (ie. "restrictive"), only modules that have a valid
6162306a36Sopenharmony_ci     signature that can be verified by a public key in the kernel's possession
6262306a36Sopenharmony_ci     will be loaded.  All other modules will generate an error.
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci     Irrespective of the setting here, if the module has a signature block that
6562306a36Sopenharmony_ci     cannot be parsed, it will be rejected out of hand.
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci (2) :menuselection:`Automatically sign all modules`
6962306a36Sopenharmony_ci     (``CONFIG_MODULE_SIG_ALL``)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci     If this is on then modules will be automatically signed during the
7262306a36Sopenharmony_ci     modules_install phase of a build.  If this is off, then the modules must
7362306a36Sopenharmony_ci     be signed manually using::
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	scripts/sign-file
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci (3) :menuselection:`Which hash algorithm should modules be signed with?`
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci     This presents a choice of which hash algorithm the installation phase will
8162306a36Sopenharmony_ci     sign the modules with:
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci        =============================== ==========================================
8462306a36Sopenharmony_ci	``CONFIG_MODULE_SIG_SHA1``	:menuselection:`Sign modules with SHA-1`
8562306a36Sopenharmony_ci	``CONFIG_MODULE_SIG_SHA224``	:menuselection:`Sign modules with SHA-224`
8662306a36Sopenharmony_ci	``CONFIG_MODULE_SIG_SHA256``	:menuselection:`Sign modules with SHA-256`
8762306a36Sopenharmony_ci	``CONFIG_MODULE_SIG_SHA384``	:menuselection:`Sign modules with SHA-384`
8862306a36Sopenharmony_ci	``CONFIG_MODULE_SIG_SHA512``	:menuselection:`Sign modules with SHA-512`
8962306a36Sopenharmony_ci        =============================== ==========================================
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci     The algorithm selected here will also be built into the kernel (rather
9262306a36Sopenharmony_ci     than being a module) so that modules signed with that algorithm can have
9362306a36Sopenharmony_ci     their signatures checked without causing a dependency loop.
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci (4) :menuselection:`File name or PKCS#11 URI of module signing key`
9762306a36Sopenharmony_ci     (``CONFIG_MODULE_SIG_KEY``)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci     Setting this option to something other than its default of
10062306a36Sopenharmony_ci     ``certs/signing_key.pem`` will disable the autogeneration of signing keys
10162306a36Sopenharmony_ci     and allow the kernel modules to be signed with a key of your choosing.
10262306a36Sopenharmony_ci     The string provided should identify a file containing both a private key
10362306a36Sopenharmony_ci     and its corresponding X.509 certificate in PEM form, or — on systems where
10462306a36Sopenharmony_ci     the OpenSSL ENGINE_pkcs11 is functional — a PKCS#11 URI as defined by
10562306a36Sopenharmony_ci     RFC7512. In the latter case, the PKCS#11 URI should reference both a
10662306a36Sopenharmony_ci     certificate and a private key.
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci     If the PEM file containing the private key is encrypted, or if the
10962306a36Sopenharmony_ci     PKCS#11 token requires a PIN, this can be provided at build time by
11062306a36Sopenharmony_ci     means of the ``KBUILD_SIGN_PIN`` variable.
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci (5) :menuselection:`Additional X.509 keys for default system keyring`
11462306a36Sopenharmony_ci     (``CONFIG_SYSTEM_TRUSTED_KEYS``)
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci     This option can be set to the filename of a PEM-encoded file containing
11762306a36Sopenharmony_ci     additional certificates which will be included in the system keyring by
11862306a36Sopenharmony_ci     default.
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciNote that enabling module signing adds a dependency on the OpenSSL devel
12162306a36Sopenharmony_cipackages to the kernel build processes for the tool that does the signing.
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci=======================
12562306a36Sopenharmony_ciGenerating signing keys
12662306a36Sopenharmony_ci=======================
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ciCryptographic keypairs are required to generate and check signatures.  A
12962306a36Sopenharmony_ciprivate key is used to generate a signature and the corresponding public key is
13062306a36Sopenharmony_ciused to check it.  The private key is only needed during the build, after which
13162306a36Sopenharmony_ciit can be deleted or stored securely.  The public key gets built into the
13262306a36Sopenharmony_cikernel so that it can be used to check the signatures as the modules are
13362306a36Sopenharmony_ciloaded.
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciUnder normal conditions, when ``CONFIG_MODULE_SIG_KEY`` is unchanged from its
13662306a36Sopenharmony_cidefault, the kernel build will automatically generate a new keypair using
13762306a36Sopenharmony_ciopenssl if one does not exist in the file::
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	certs/signing_key.pem
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ciduring the building of vmlinux (the public part of the key needs to be built
14262306a36Sopenharmony_ciinto vmlinux) using parameters in the::
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	certs/x509.genkey
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cifile (which is also generated if it does not already exist).
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ciIt is strongly recommended that you provide your own x509.genkey file.
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciMost notably, in the x509.genkey file, the req_distinguished_name section
15162306a36Sopenharmony_cishould be altered from the default::
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	[ req_distinguished_name ]
15462306a36Sopenharmony_ci	#O = Unspecified company
15562306a36Sopenharmony_ci	CN = Build time autogenerated kernel key
15662306a36Sopenharmony_ci	#emailAddress = unspecified.user@unspecified.company
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciThe generated RSA key size can also be set with::
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	[ req ]
16162306a36Sopenharmony_ci	default_bits = 4096
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciIt is also possible to manually generate the key private/public files using the
16562306a36Sopenharmony_cix509.genkey key generation configuration file in the root node of the Linux
16662306a36Sopenharmony_cikernel sources tree and the openssl command.  The following is an example to
16762306a36Sopenharmony_cigenerate the public/private key files::
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
17062306a36Sopenharmony_ci	   -config x509.genkey -outform PEM -out kernel_key.pem \
17162306a36Sopenharmony_ci	   -keyout kernel_key.pem
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ciThe full pathname for the resulting kernel_key.pem file can then be specified
17462306a36Sopenharmony_ciin the ``CONFIG_MODULE_SIG_KEY`` option, and the certificate and key therein will
17562306a36Sopenharmony_cibe used instead of an autogenerated keypair.
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci=========================
17962306a36Sopenharmony_ciPublic keys in the kernel
18062306a36Sopenharmony_ci=========================
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ciThe kernel contains a ring of public keys that can be viewed by root.  They're
18362306a36Sopenharmony_ciin a keyring called ".builtin_trusted_keys" that can be seen by::
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	[root@deneb ~]# cat /proc/keys
18662306a36Sopenharmony_ci	...
18762306a36Sopenharmony_ci	223c7853 I------     1 perm 1f030000     0     0 keyring   .builtin_trusted_keys: 1
18862306a36Sopenharmony_ci	302d2d52 I------     1 perm 1f010000     0     0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
18962306a36Sopenharmony_ci	...
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciBeyond the public key generated specifically for module signing, additional
19262306a36Sopenharmony_citrusted certificates can be provided in a PEM-encoded file referenced by the
19362306a36Sopenharmony_ci``CONFIG_SYSTEM_TRUSTED_KEYS`` configuration option.
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciFurther, the architecture code may take public keys from a hardware store and
19662306a36Sopenharmony_ciadd those in also (e.g. from the UEFI key database).
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ciFinally, it is possible to add additional public keys by doing::
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	keyctl padd asymmetric "" [.builtin_trusted_keys-ID] <[key-file]
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cie.g.::
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciNote, however, that the kernel will only permit keys to be added to
20762306a36Sopenharmony_ci``.builtin_trusted_keys`` **if** the new key's X.509 wrapper is validly signed by a key
20862306a36Sopenharmony_cithat is already resident in the ``.builtin_trusted_keys`` at the time the key was added.
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci========================
21262306a36Sopenharmony_ciManually signing modules
21362306a36Sopenharmony_ci========================
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ciTo manually sign a module, use the scripts/sign-file tool available in
21662306a36Sopenharmony_cithe Linux kernel source tree.  The script requires 4 arguments:
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	1.  The hash algorithm (e.g., sha256)
21962306a36Sopenharmony_ci	2.  The private key filename or PKCS#11 URI
22062306a36Sopenharmony_ci	3.  The public key filename
22162306a36Sopenharmony_ci	4.  The kernel module to be signed
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ciThe following is an example to sign a kernel module::
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	scripts/sign-file sha512 kernel-signkey.priv \
22662306a36Sopenharmony_ci		kernel-signkey.x509 module.ko
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciThe hash algorithm used does not have to match the one configured, but if it
22962306a36Sopenharmony_cidoesn't, you should make sure that hash algorithm is either built into the
23062306a36Sopenharmony_cikernel or can be loaded without requiring itself.
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ciIf the private key requires a passphrase or PIN, it can be provided in the
23362306a36Sopenharmony_ci$KBUILD_SIGN_PIN environment variable.
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci============================
23762306a36Sopenharmony_ciSigned modules and stripping
23862306a36Sopenharmony_ci============================
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ciA signed module has a digital signature simply appended at the end.  The string
24162306a36Sopenharmony_ci``~Module signature appended~.`` at the end of the module's file confirms that a
24262306a36Sopenharmony_cisignature is present but it does not confirm that the signature is valid!
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ciSigned modules are BRITTLE as the signature is outside of the defined ELF
24562306a36Sopenharmony_cicontainer.  Thus they MAY NOT be stripped once the signature is computed and
24662306a36Sopenharmony_ciattached.  Note the entire module is the signed payload, including any and all
24762306a36Sopenharmony_cidebug information present at the time of signing.
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci======================
25162306a36Sopenharmony_ciLoading signed modules
25262306a36Sopenharmony_ci======================
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ciModules are loaded with insmod, modprobe, ``init_module()`` or
25562306a36Sopenharmony_ci``finit_module()``, exactly as for unsigned modules as no processing is
25662306a36Sopenharmony_cidone in userspace.  The signature checking is all done within the kernel.
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci=========================================
26062306a36Sopenharmony_ciNon-valid signatures and unsigned modules
26162306a36Sopenharmony_ci=========================================
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ciIf ``CONFIG_MODULE_SIG_FORCE`` is enabled or module.sig_enforce=1 is supplied on
26462306a36Sopenharmony_cithe kernel command line, the kernel will only load validly signed modules
26562306a36Sopenharmony_cifor which it has a public key.   Otherwise, it will also load modules that are
26662306a36Sopenharmony_ciunsigned.   Any module for which the kernel has a key, but which proves to have
26762306a36Sopenharmony_cia signature mismatch will not be permitted to load.
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ciAny module that has an unparsable signature will be rejected.
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci=========================================
27362306a36Sopenharmony_ciAdministering/protecting the private key
27462306a36Sopenharmony_ci=========================================
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ciSince the private key is used to sign modules, viruses and malware could use
27762306a36Sopenharmony_cithe private key to sign modules and compromise the operating system.  The
27862306a36Sopenharmony_ciprivate key must be either destroyed or moved to a secure location and not kept
27962306a36Sopenharmony_ciin the root node of the kernel source tree.
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ciIf you use the same private key to sign modules for multiple kernel
28262306a36Sopenharmony_ciconfigurations, you must ensure that the module version information is
28362306a36Sopenharmony_cisufficient to prevent loading a module into a different kernel.  Either
28462306a36Sopenharmony_ciset ``CONFIG_MODVERSIONS=y`` or ensure that each configuration has a different
28562306a36Sopenharmony_cikernel release string by changing ``EXTRAVERSION`` or ``CONFIG_LOCALVERSION``.
286