diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 18:05:18 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 18:05:18 +0300 |
commit | f2586d921cea4feeddd1cc5ee3495700540dba8f (patch) | |
tree | 7207a1e8c8eb1f4f67f1e2987df12c6a81485184 /security/integrity | |
parent | 1c59d383390f970b891b503b7f79b63a02db2ec5 (diff) | |
parent | 218a2680624cba1611e3dfc7d9b646d240e5f855 (diff) | |
download | linux-f2586d921cea4feeddd1cc5ee3495700540dba8f.tar.xz |
Merge tag 'tpmdd-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen:
- Restrict linking of keys to .ima and .evm keyrings based on
digitalSignature attribute in the certificate
- PowerVM: load machine owner keys into the .machine [1] keyring
- PowerVM: load module signing keys into the secondary trusted keyring
(keys blessed by the vendor)
- tpm_tis_spi: half-duplex transfer mode
- tpm_tis: retry corrupted transfers
- Apply revocation list (.mokx) to an all system keyrings (e.g.
.machine keyring)
Link: https://blogs.oracle.com/linux/post/the-machine-keyring [1]
* tag 'tpmdd-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
certs: Reference revocation list for all keyrings
tpm/tpm_tis_synquacer: Use module_platform_driver macro to simplify the code
tpm: remove redundant variable len
tpm_tis: Resend command to recover from data transfer errors
tpm_tis: Use responseRetry to recover from data transfer errors
tpm_tis: Move CRC check to generic send routine
tpm_tis_spi: Add hardware wait polling
KEYS: Replace all non-returning strlcpy with strscpy
integrity: PowerVM support for loading third party code signing keys
integrity: PowerVM machine keyring enablement
integrity: check whether imputed trust is enabled
integrity: remove global variable from machine_keyring.c
integrity: ignore keys failing CA restrictions on non-UEFI platform
integrity: PowerVM support for loading CA keys on machine keyring
integrity: Enforce digitalSignature usage in the ima and evm keyrings
KEYS: DigitalSignature link restriction
tpm_tis: Revert "tpm_tis: Disable interrupts on ThinkPad T490s"
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/Kconfig | 4 | ||||
-rw-r--r-- | security/integrity/digsig.c | 6 | ||||
-rw-r--r-- | security/integrity/evm/Kconfig | 3 | ||||
-rw-r--r-- | security/integrity/ima/Kconfig | 3 | ||||
-rw-r--r-- | security/integrity/integrity.h | 5 | ||||
-rw-r--r-- | security/integrity/platform_certs/keyring_handler.c | 19 | ||||
-rw-r--r-- | security/integrity/platform_certs/keyring_handler.h | 10 | ||||
-rw-r--r-- | security/integrity/platform_certs/load_powerpc.c | 34 | ||||
-rw-r--r-- | security/integrity/platform_certs/machine_keyring.c | 22 |
9 files changed, 93 insertions, 13 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index ec6e0d789da1..232191ee09e3 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -67,7 +67,9 @@ config INTEGRITY_MACHINE_KEYRING depends on SECONDARY_TRUSTED_KEYRING depends on INTEGRITY_ASYMMETRIC_KEYS depends on SYSTEM_BLACKLIST_KEYRING - depends on LOAD_UEFI_KEYS + depends on LOAD_UEFI_KEYS || LOAD_PPC_KEYS + select INTEGRITY_CA_MACHINE_KEYRING if LOAD_PPC_KEYS + select INTEGRITY_CA_MACHINE_KEYRING_MAX if LOAD_PPC_KEYS help If set, provide a keyring to which Machine Owner Keys (MOK) may be added. This keyring shall contain just MOK keys. Unlike keys diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 6f31ffe23c48..df387de29bfa 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -34,9 +34,9 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { }; #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY -#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted +#define restrict_link_to_ima restrict_link_by_digsig_builtin_and_secondary #else -#define restrict_link_to_ima restrict_link_by_builtin_trusted +#define restrict_link_to_ima restrict_link_by_digsig_builtin #endif static struct key *integrity_keyring_from_id(const unsigned int id) @@ -113,7 +113,7 @@ 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_MACHINE && trust_moklist()) + if (id == INTEGRITY_KEYRING_MACHINE && imputed_trust_enabled()) set_machine_trusted_keys(keyring[id]); if (id == INTEGRITY_KEYRING_IMA) load_module_cert(keyring[id]); diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig index a6e19d23e700..fba9ee359bc9 100644 --- a/security/integrity/evm/Kconfig +++ b/security/integrity/evm/Kconfig @@ -64,7 +64,8 @@ config EVM_LOAD_X509 This option enables X509 certificate loading from the kernel onto the '.evm' trusted keyring. A public key can be used to - verify EVM integrity starting from the 'init' process. + verify EVM integrity starting from the 'init' process. The + key must have digitalSignature usage set. config EVM_X509_PATH string "EVM X509 certificate path" diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 60a511c6b583..684425936c53 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -270,7 +270,8 @@ config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY help Keys may be added to the IMA or IMA blacklist keyrings, if the key is validly signed by a CA cert in the system built-in or - secondary trusted keyrings. + secondary trusted keyrings. The key must also have the + digitalSignature usage set. Intermediate keys between those the kernel has compiled in and the IMA keys to be added may be added to the system secondary keyring, diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 7167a6e99bdc..d7553c93f5c0 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -320,13 +320,14 @@ static inline void __init add_to_platform_keyring(const char *source, #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING void __init add_to_machine_keyring(const char *source, const void *data, size_t len); -bool __init trust_moklist(void); +bool __init imputed_trust_enabled(void); #else static inline void __init add_to_machine_keyring(const char *source, const void *data, size_t len) { } -static inline bool __init trust_moklist(void) + +static inline bool __init imputed_trust_enabled(void) { return false; } diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c index 8a1124e4d769..13ea17207902 100644 --- a/security/integrity/platform_certs/keyring_handler.c +++ b/security/integrity/platform_certs/keyring_handler.c @@ -61,7 +61,8 @@ __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type) __init efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type) { if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) { - if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && trust_moklist()) + if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && + imputed_trust_enabled()) return add_to_machine_keyring; else return add_to_platform_keyring; @@ -69,6 +70,22 @@ __init efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type) return NULL; } +__init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type) +{ + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) + return add_to_machine_keyring; + + return NULL; +} + +__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type) +{ + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) + return add_to_secondary_keyring; + + return NULL; +} + /* * Return the appropriate handler for particular signature list types found in * the UEFI dbx and MokListXRT tables. diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h index 212d894a8c0c..f92895cc50f6 100644 --- a/security/integrity/platform_certs/keyring_handler.h +++ b/security/integrity/platform_certs/keyring_handler.h @@ -30,6 +30,16 @@ efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type); efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type); /* + * Return the handler for particular signature list types for CA keys. + */ +efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type); + +/* + * Return the handler for particular signature list types for code signing keys. + */ +efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type); + +/* * Return the handler for particular signature list types found in the dbx. */ efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type); diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c index 170789dc63d2..c85febca3343 100644 --- a/security/integrity/platform_certs/load_powerpc.c +++ b/security/integrity/platform_certs/load_powerpc.c @@ -59,6 +59,8 @@ static __init void *get_cert_list(u8 *key, unsigned long keylen, u64 *size) static int __init load_powerpc_certs(void) { void *db = NULL, *dbx = NULL, *data = NULL; + void *trustedca; + void *moduledb; u64 dsize = 0; u64 offset = 0; int rc = 0; @@ -120,6 +122,38 @@ static int __init load_powerpc_certs(void) kfree(data); } + data = get_cert_list("trustedcadb", 12, &dsize); + if (!data) { + pr_info("Couldn't get trustedcadb list from firmware\n"); + } else if (IS_ERR(data)) { + rc = PTR_ERR(data); + pr_err("Error reading trustedcadb from firmware: %d\n", rc); + } else { + extract_esl(trustedca, data, dsize, offset); + + rc = parse_efi_signature_list("powerpc:trustedca", trustedca, dsize, + get_handler_for_ca_keys); + if (rc) + pr_err("Couldn't parse trustedcadb signatures: %d\n", rc); + kfree(data); + } + + data = get_cert_list("moduledb", 9, &dsize); + if (!data) { + pr_info("Couldn't get moduledb list from firmware\n"); + } else if (IS_ERR(data)) { + rc = PTR_ERR(data); + pr_err("Error reading moduledb from firmware: %d\n", rc); + } else { + extract_esl(moduledb, data, dsize, offset); + + rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize, + get_handler_for_code_signing_keys); + if (rc) + pr_err("Couldn't parse moduledb signatures: %d\n", rc); + kfree(data); + } + return rc; } late_initcall(load_powerpc_certs); diff --git a/security/integrity/platform_certs/machine_keyring.c b/security/integrity/platform_certs/machine_keyring.c index 7aaed7950b6e..a401640a63cd 100644 --- a/security/integrity/platform_certs/machine_keyring.c +++ b/security/integrity/platform_certs/machine_keyring.c @@ -8,8 +8,6 @@ #include <linux/efi.h> #include "../integrity.h" -static bool trust_mok; - static __init int machine_keyring_init(void) { int rc; @@ -36,7 +34,8 @@ void __init add_to_machine_keyring(const char *source, const void *data, size_t * If the restriction check does not pass and the platform keyring * is configured, try to add it into that keyring instead. */ - if (rc && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) + if (rc && efi_enabled(EFI_BOOT) && + IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len, perm); @@ -62,12 +61,14 @@ static __init bool uefi_check_trust_mok_keys(void) return false; } -bool __init trust_moklist(void) +static bool __init trust_moklist(void) { static bool initialized; + static bool trust_mok; if (!initialized) { initialized = true; + trust_mok = false; if (uefi_check_trust_mok_keys()) trust_mok = true; @@ -75,3 +76,16 @@ bool __init trust_moklist(void) return trust_mok; } + +/* + * Provides platform specific check for trusting imputed keys before loading + * on .machine keyring. UEFI systems enable this trust based on a variable, + * and for other platforms, it is always enabled. + */ +bool __init imputed_trust_enabled(void) +{ + if (efi_enabled(EFI_BOOT)) + return trust_moklist(); + + return true; +} |