From 4520c6a49af833c83de6c74525ce8e07bbe6d783 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 21 Sep 2012 23:31:13 +0100 Subject: X.509: Add simple ASN.1 grammar compiler Add a simple ASN.1 grammar compiler. This produces a bytecode output that can be fed to a decoder to inform the decoder how to interpret the ASN.1 stream it is trying to parse. Action functions can be specified in the grammar by interpolating: ({ foo }) after a type, for example: SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING ({ do_key_data }) } The decoder is expected to call these after matching this type and parsing the contents if it is a constructed type. The grammar compiler does not currently support the SET type (though it does support SET OF) as I can't see a good way of tracking which members have been encountered yet without using up extra stack space. Currently, the grammar compiler will fail if more than 256 bytes of bytecode would be produced or more than 256 actions have been specified as it uses 8-bit jump values and action indices to keep space usage down. Signed-off-by: David Howells Signed-off-by: Rusty Russell --- init/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index af6c7f8ba019..66cc885abbc6 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1612,4 +1612,12 @@ config PADATA depends on SMP bool +config ASN1 + tristate + help + Build a simple ASN.1 grammar compiler that produces a bytecode output + that can be interpreted by the ASN.1 stream decoder and used to + inform it as to what tags are to be expected in a stream and what + functions to call on what tags. + source "kernel/Kconfig.locks" -- cgit From 106a4ee258d14818467829bf0e12aeae14c16cd7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 26 Sep 2012 10:09:40 +0100 Subject: module: signature checking hook We do a very simple search for a particular string appended to the module (which is cache-hot and about to be SHA'd anyway). There's both a config option and a boot parameter which control whether we accept or fail with unsigned modules and modules that are signed with an unknown key. If module signing is enabled, the kernel will be tainted if a module is loaded that is unsigned or has a signature for which we don't have the key. (Useful feedback and tweaks by David Howells ) Signed-off-by: Rusty Russell Signed-off-by: David Howells Signed-off-by: Rusty Russell --- init/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index 66cc885abbc6..fa8ccad1ea43 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1585,6 +1585,20 @@ config MODULE_SRCVERSION_ALL the version). With this option, such a "srcversion" field will be created for all modules. If unsure, say N. +config MODULE_SIG + bool "Module signature verification" + depends on MODULES + help + Check modules for valid signatures upon load: the signature + is simply appended to the module. For more information see + Documentation/module-signing.txt. + +config MODULE_SIG_FORCE + bool "Require modules to be validly signed" + depends on MODULE_SIG + help + Reject unsigned modules or signed modules for which we don't have a + key. Without this, such modules will simply taint the kernel. endif # MODULES config INIT_ALL_POSSIBLE -- cgit From ea0b6dcf71d216dc11733ac19b26df0f5d0fd6c2 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 26 Sep 2012 10:09:50 +0100 Subject: MODSIGN: Provide Kconfig options Provide kernel configuration options for module signing. The following configuration options are added: CONFIG_MODULE_SIG_SHA1 CONFIG_MODULE_SIG_SHA224 CONFIG_MODULE_SIG_SHA256 CONFIG_MODULE_SIG_SHA384 CONFIG_MODULE_SIG_SHA512 These select the cryptographic hash used to digest the data prior to signing. Additionally, the crypto module selected will be built into the kernel as it won't be possible to load it as a module without incurring a circular dependency when the kernel tries to check its signature. Signed-off-by: David Howells Signed-off-by: Rusty Russell --- init/Kconfig | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index fa8ccad1ea43..00d45799dee1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1593,12 +1593,50 @@ config MODULE_SIG is simply appended to the module. For more information see Documentation/module-signing.txt. + !!!WARNING!!! If you enable this option, you MUST make sure that the + module DOES NOT get stripped after being signed. This includes the + debuginfo strip done by some packagers (such as rpmbuild) and + inclusion into an initramfs that wants the module size reduced. + config MODULE_SIG_FORCE bool "Require modules to be validly signed" depends on MODULE_SIG help Reject unsigned modules or signed modules for which we don't have a key. Without this, such modules will simply taint the kernel. + +choice + prompt "Which hash algorithm should modules be signed with?" + depends on MODULE_SIG + help + This determines which sort of hashing algorithm will be used during + signature generation. This algorithm _must_ be built into the kernel + directly so that signature verification can take place. It is not + possible to load a signed module containing the algorithm to check + the signature on that module. + +config MODULE_SIG_SHA1 + bool "Sign modules with SHA-1" + select CRYPTO_SHA1 + +config MODULE_SIG_SHA224 + bool "Sign modules with SHA-224" + select CRYPTO_SHA256 + +config MODULE_SIG_SHA256 + bool "Sign modules with SHA-256" + select CRYPTO_SHA256 + +config MODULE_SIG_SHA384 + bool "Sign modules with SHA-384" + select CRYPTO_SHA512 + +config MODULE_SIG_SHA512 + bool "Sign modules with SHA-512" + select CRYPTO_SHA512 + +endchoice + endif # MODULES config INIT_ALL_POSSIBLE -- cgit From 48ba2462ace6072741fd8d0058207d630ce93bf1 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 26 Sep 2012 10:11:03 +0100 Subject: MODSIGN: Implement module signature checking Check the signature on the module against the keys compiled into the kernel or available in a hardware key store. Currently, only RSA keys are supported - though that's easy enough to change, and the signature is expected to contain raw components (so not a PGP or PKCS#7 formatted blob). The signature blob is expected to consist of the following pieces in order: (1) The binary identifier for the key. This is expected to match the SubjectKeyIdentifier from an X.509 certificate. Only X.509 type identifiers are currently supported. (2) The signature data, consisting of a series of MPIs in which each is in the format of a 2-byte BE word sizes followed by the content data. (3) A 12 byte information block of the form: struct module_signature { enum pkey_algo algo : 8; enum pkey_hash_algo hash : 8; enum pkey_id_type id_type : 8; u8 __pad; __be32 id_length; __be32 sig_length; }; The three enums are defined in crypto/public_key.h. 'algo' contains the public-key algorithm identifier (0->DSA, 1->RSA). 'hash' contains the digest algorithm identifier (0->MD4, 1->MD5, 2->SHA1, etc.). 'id_type' contains the public-key identifier type (0->PGP, 1->X.509). '__pad' should be 0. 'id_length' should contain in the binary identifier length in BE form. 'sig_length' should contain in the signature data length in BE form. The lengths are in BE order rather than CPU order to make dealing with cross-compilation easier. Signed-off-by: David Howells Signed-off-by: Rusty Russell (minor Kconfig fix) --- init/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index 00d45799dee1..abc6e63f2fb8 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1588,6 +1588,14 @@ config MODULE_SRCVERSION_ALL config MODULE_SIG bool "Module signature verification" depends on MODULES + select KEYS + select CRYPTO + select ASYMMETRIC_KEY_TYPE + select ASYMMETRIC_PUBLIC_KEY_SUBTYPE + select PUBLIC_KEY_ALGO_RSA + select ASN1 + select OID_REGISTRY + select X509_CERTIFICATE_PARSER help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see -- cgit