1 // SPDX-License-Identifier: GPL-2.0
3 * Verification of builtin signatures
5 * Copyright 2019 Google LLC
9 * This file implements verification of fs-verity builtin signatures. Please
10 * take great care before using this feature. It is not the only way to do
11 * signatures with fs-verity, and the alternatives (such as userspace signature
12 * verification, and IMA appraisal) can be much better. For details about the
13 * limitations of this feature, see Documentation/filesystems/fsverity.rst.
16 #include "fsverity_private.h"
18 #include <linux/cred.h>
19 #include <linux/key.h>
20 #include <linux/security.h>
21 #include <linux/slab.h>
22 #include <linux/verification.h>
25 * /proc/sys/fs/verity/require_signatures
26 * If 1, all verity files must have a valid builtin signature.
28 int fsverity_require_signatures
;
31 * Keyring that contains the trusted X.509 certificates.
33 * Only root (kuid=0) can modify this. Also, root may use
34 * keyctl_restrict_keyring() to prevent any more additions.
36 static struct key
*fsverity_keyring
;
39 * fsverity_verify_signature() - check a verity file's signature
40 * @vi: the file's fsverity_info
41 * @signature: the file's built-in signature
42 * @sig_size: size of signature in bytes, or 0 if no signature
44 * If the file includes a signature of its fs-verity file digest, verify it
45 * against the certificates in the fs-verity keyring. Note that signatures
46 * are verified regardless of the state of the 'fsverity_require_signatures'
47 * variable and the LSM subsystem relies on this behavior to help enforce
48 * file integrity policies. Please discuss changes with the LSM list
51 * Return: 0 on success (signature valid or not required); -errno on failure
53 int fsverity_verify_signature(const struct fsverity_info
*vi
,
54 const u8
*signature
, size_t sig_size
)
56 const struct inode
*inode
= vi
->inode
;
57 const struct fsverity_hash_alg
*hash_alg
= vi
->tree_params
.hash_alg
;
58 struct fsverity_formatted_digest
*d
;
62 if (fsverity_require_signatures
) {
64 "require_signatures=1, rejecting unsigned file!");
70 if (fsverity_keyring
->keys
.nr_leaves_on_tree
== 0) {
72 * The ".fs-verity" keyring is empty, due to builtin signatures
73 * being supported by the kernel but not actually being used.
74 * In this case, verify_pkcs7_signature() would always return an
75 * error, usually ENOKEY. It could also be EBADMSG if the
76 * PKCS#7 is malformed, but that isn't very important to
77 * distinguish. So, just skip to ENOKEY to avoid the attack
78 * surface of the PKCS#7 parser, which would otherwise be
79 * reachable by any task able to execute FS_IOC_ENABLE_VERITY.
82 "fs-verity keyring is empty, rejecting signed file!");
86 d
= kzalloc(sizeof(*d
) + hash_alg
->digest_size
, GFP_KERNEL
);
89 memcpy(d
->magic
, "FSVerity", 8);
90 d
->digest_algorithm
= cpu_to_le16(hash_alg
- fsverity_hash_algs
);
91 d
->digest_size
= cpu_to_le16(hash_alg
->digest_size
);
92 memcpy(d
->digest
, vi
->file_digest
, hash_alg
->digest_size
);
94 err
= verify_pkcs7_signature(d
, sizeof(*d
) + hash_alg
->digest_size
,
95 signature
, sig_size
, fsverity_keyring
,
96 VERIFYING_UNSPECIFIED_SIGNATURE
,
103 "File's signing cert isn't in the fs-verity keyring");
104 else if (err
== -EKEYREJECTED
)
105 fsverity_err(inode
, "Incorrect file signature");
106 else if (err
== -EBADMSG
)
107 fsverity_err(inode
, "Malformed file signature");
109 fsverity_err(inode
, "Error %d verifying file signature",
114 err
= security_inode_setintegrity(inode
,
115 LSM_INT_FSVERITY_BUILTINSIG_VALID
,
120 fsverity_err(inode
, "Error %d exposing file signature to LSMs",
128 void __init
fsverity_init_signature(void)
131 keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0),
132 current_cred(), KEY_POS_SEARCH
|
133 KEY_USR_VIEW
| KEY_USR_READ
| KEY_USR_WRITE
|
134 KEY_USR_SEARCH
| KEY_USR_SETATTR
,
135 KEY_ALLOC_NOT_IN_QUOTA
, NULL
, NULL
);
136 if (IS_ERR(fsverity_keyring
))
137 panic("failed to allocate \".fs-verity\" keyring");