^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Verification of builtin signatures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2019 Google LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "fsverity_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/cred.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/verification.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * /proc/sys/fs/verity/require_signatures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * If 1, all verity files must have a valid builtin signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int fsverity_require_signatures;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Keyring that contains the trusted X.509 certificates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Only root (kuid=0) can modify this. Also, root may use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * keyctl_restrict_keyring() to prevent any more additions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct key *fsverity_keyring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * fsverity_verify_signature() - check a verity file's signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * @vi: the file's fsverity_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @signature: the file's built-in signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @sig_size: size of signature in bytes, or 0 if no signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * If the file includes a signature of its fs-verity file digest, verify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * against the certificates in the fs-verity keyring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Return: 0 on success (signature valid or not required); -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int fsverity_verify_signature(const struct fsverity_info *vi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const u8 *signature, size_t sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int digest_algorithm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) vi->tree_params.hash_alg - fsverity_hash_algs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return __fsverity_verify_signature(vi->inode, signature, sig_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) vi->file_digest, digest_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * __fsverity_verify_signature() - check a verity file's signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @inode: the file's inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @signature: the file's signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @sig_size: size of @signature. Can be 0 if there is no signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @file_digest: the file's digest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @digest_algorithm: the digest algorithm used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Takes the file's digest and optional signature and verifies the signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * against the digest and the fs-verity keyring if appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Return: 0 on success (signature valid or not required); -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int __fsverity_verify_signature(const struct inode *inode, const u8 *signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) size_t sig_size, const u8 *file_digest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int digest_algorithm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct fsverity_formatted_digest *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct fsverity_hash_alg *hash_alg = fsverity_get_hash_alg(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) digest_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (IS_ERR(hash_alg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return PTR_ERR(hash_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (sig_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (fsverity_require_signatures) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) fsverity_err(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "require_signatures=1, rejecting unsigned file!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) memcpy(d->magic, "FSVerity", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) d->digest_algorithm = cpu_to_le16(hash_alg - fsverity_hash_algs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) d->digest_size = cpu_to_le16(hash_alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) memcpy(d->digest, file_digest, hash_alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) signature, sig_size, fsverity_keyring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) VERIFYING_UNSPECIFIED_SIGNATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) kfree(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (err == -ENOKEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) fsverity_err(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) "File's signing cert isn't in the fs-verity keyring");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) else if (err == -EKEYREJECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) fsverity_err(inode, "Incorrect file signature");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) else if (err == -EBADMSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) fsverity_err(inode, "Malformed file signature");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) fsverity_err(inode, "Error %d verifying file signature",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) pr_debug("Valid signature for file digest %s:%*phN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) hash_alg->name, hash_alg->digest_size, file_digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXPORT_SYMBOL_GPL(__fsverity_verify_signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static struct ctl_table_header *fsverity_sysctl_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static const struct ctl_path fsverity_sysctl_path[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { .procname = "fs", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { .procname = "verity", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static struct ctl_table fsverity_sysctl_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .procname = "require_signatures",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .data = &fsverity_require_signatures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .proc_handler = proc_dointvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .extra1 = SYSCTL_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .extra2 = SYSCTL_ONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int __init fsverity_sysctl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) fsverity_sysctl_header = register_sysctl_paths(fsverity_sysctl_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) fsverity_sysctl_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!fsverity_sysctl_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pr_err("sysctl registration failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #else /* !CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static inline int __init fsverity_sysctl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #endif /* !CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int __init fsverity_init_signature(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct key *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ring = keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) current_cred(), KEY_POS_SEARCH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) KEY_USR_SEARCH | KEY_USR_SETATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (IS_ERR(ring))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return PTR_ERR(ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = fsverity_sysctl_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto err_put_ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) fsverity_keyring = ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) err_put_ring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) key_put(ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }