Linux 6.9-rc4
[sfrench/cifs-2.6.git] / security / integrity / digsig.c
index 250fb08361564f4c8bdbb7072189d1a48225390d..45c3e5dda355e23f823086816d00e78071b1c15c 100644 (file)
@@ -30,12 +30,13 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
        ".ima",
 #endif
        ".platform",
+       ".machine",
 };
 
 #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)
@@ -74,7 +75,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
                /* v1 API expect signature without xattr type */
                return digsig_verify(keyring, sig + 1, siglen - 1, digest,
                                     digestlen);
-       case 2:
+       case 2: /* regular file data hash based signature */
+       case 3: /* struct ima_file_id data based signature */
                return asymmetric_verify(keyring, sig, siglen, digest,
                                         digestlen);
        }
@@ -111,6 +113,10 @@ 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 && imputed_trust_enabled())
+                       set_machine_trusted_keys(keyring[id]);
+               if (id == INTEGRITY_KEYRING_IMA)
+                       load_module_cert(keyring[id]);
        }
 
        return err;
@@ -120,11 +126,14 @@ int __init integrity_init_keyring(const unsigned int id)
 {
        struct key_restriction *restriction;
        key_perm_t perm;
+       int ret;
 
        perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
                | KEY_USR_READ | KEY_USR_SEARCH;
 
-       if (id == INTEGRITY_KEYRING_PLATFORM) {
+       if (id == INTEGRITY_KEYRING_PLATFORM ||
+           (id == INTEGRITY_KEYRING_MACHINE &&
+           !IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) {
                restriction = NULL;
                goto out;
        }
@@ -136,11 +145,24 @@ int __init integrity_init_keyring(const unsigned int id)
        if (!restriction)
                return -ENOMEM;
 
-       restriction->check = restrict_link_to_ima;
-       perm |= KEY_USR_WRITE;
+       if (id == INTEGRITY_KEYRING_MACHINE)
+               restriction->check = restrict_link_by_ca;
+       else
+               restriction->check = restrict_link_to_ima;
+
+       /*
+        * MOK keys can only be added through a read-only runtime services
+        * UEFI variable during boot. No additional keys shall be allowed to
+        * load into the machine keyring following init from userspace.
+        */
+       if (id != INTEGRITY_KEYRING_MACHINE)
+               perm |= KEY_USR_WRITE;
 
 out:
-       return __integrity_init_keyring(id, perm, restriction);
+       ret = __integrity_init_keyring(id, perm, restriction);
+       if (ret)
+               kfree(restriction);
+       return ret;
 }
 
 static int __init integrity_add_key(const unsigned int id, const void *data,
@@ -157,7 +179,8 @@ static int __init integrity_add_key(const unsigned int id, const void *data,
                                   KEY_ALLOC_NOT_IN_QUOTA);
        if (IS_ERR(key)) {
                rc = PTR_ERR(key);
-               pr_err("Problem loading X.509 certificate %d\n", rc);
+               if (id != INTEGRITY_KEYRING_MACHINE)
+                       pr_err("Problem loading X.509 certificate %d\n", rc);
        } else {
                pr_notice("Loaded X.509 cert '%s'\n",
                          key_ref_to_ptr(key)->description);