diff --git a/certs/system_certificates.S b/certs/system_certificates.S index 8f29058adf93..dcad27ea8527 100644 --- a/certs/system_certificates.S +++ b/certs/system_certificates.S @@ -8,9 +8,11 @@ .globl system_certificate_list system_certificate_list: __cert_list_start: -#ifdef CONFIG_MODULE_SIG +__module_cert_start: +#if defined(CONFIG_MODULE_SIG) || defined(CONFIG_IMA_APPRAISE_MODSIG) .incbin "certs/signing_key.x509" #endif +__module_cert_end: .incbin "certs/x509_certificate_list" __cert_list_end: @@ -35,3 +37,12 @@ system_certificate_list_size: #else .long __cert_list_end - __cert_list_start #endif + + .align 8 + .globl module_cert_size +module_cert_size: +#ifdef CONFIG_64BIT + .quad __module_cert_end - __module_cert_start +#else + .long __module_cert_end - __module_cert_start +#endif diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 4b693da488f1..2b3ad375ecc1 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -27,6 +27,7 @@ static struct key *platform_trusted_keys; extern __initconst const u8 system_certificate_list[]; extern __initconst const unsigned long system_certificate_list_size; +extern __initconst const unsigned long module_cert_size; /** * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA @@ -132,19 +133,11 @@ static __init int system_trusted_keyring_init(void) */ device_initcall(system_trusted_keyring_init); -/* - * Load the compiled-in list of X.509 certificates. - */ -static __init int load_system_certificate_list(void) +static __init int load_cert(const u8 *p, const u8 *end, struct key *keyring) { key_ref_t key; - const u8 *p, *end; size_t plen; - pr_notice("Loading compiled-in X.509 certificates\n"); - - p = system_certificate_list; - end = p + system_certificate_list_size; while (p < end) { /* Each cert begins with an ASN.1 SEQUENCE tag and must be more * than 256 bytes in size. @@ -159,7 +152,7 @@ static __init int load_system_certificate_list(void) if (plen > end - p) goto dodgy_cert; - key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), + key = key_create_or_update(make_key_ref(keyring, 1), "asymmetric", NULL, p, @@ -186,6 +179,43 @@ static __init int load_system_certificate_list(void) pr_err("Problem parsing in-kernel X.509 certificate list\n"); return 0; } + +__init int load_module_cert(struct key *keyring) +{ + const u8 *p, *end; + + if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG)) + return 0; + + pr_notice("Loading compiled-in module X.509 certificates\n"); + + p = system_certificate_list; + end = p + module_cert_size; + + return load_cert(p, end, keyring); +} + +/* + * Load the compiled-in list of X.509 certificates. + */ +static __init int load_system_certificate_list(void) +{ + const u8 *p, *end; + unsigned long size; + + pr_notice("Loading compiled-in X.509 certificates\n"); + +#ifdef CONFIG_MODULE_SIG + p = system_certificate_list; + size = system_certificate_list_size; +#else + p = system_certificate_list + module_cert_size; + size = system_certificate_list_size - module_cert_size; +#endif + + end = p + size; + return load_cert(p, end, builtin_trusted_keys); +} late_initcall(load_system_certificate_list); #ifdef CONFIG_SYSTEM_DATA_VERIFICATION diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index fb8b07daa9d1..f954276c616a 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -16,9 +16,16 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring, const struct key_type *type, const union key_payload *payload, struct key *restriction_key); +extern __init int load_module_cert(struct key *keyring); #else #define restrict_link_by_builtin_trusted restrict_link_reject + +static inline __init int load_module_cert(struct key *keyring) +{ + return 0; +} + #endif #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 250fb0836156..3b06a01bd0fd 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -111,6 +111,8 @@ static int __init __integrity_init_keyring(const unsigned int id, } else { if (id == INTEGRITY_KEYRING_PLATFORM) set_platform_trusted_keys(keyring[id]); + if (id == INTEGRITY_KEYRING_IMA) + load_module_cert(keyring[id]); } return err;