Clarify the purpose of built-in signatures

Signed-off-by: Eric Biggers <>
diff --git a/ b/
index 14c7bbe..ffa25fd 100644
--- a/
+++ b/
@@ -102,11 +102,44 @@
 ### Using builtin signatures
-With `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`, the filesystem supports
-automatically verifying a signed file digest that has been included in
-the verity metadata.  The signature is verified against the set of
-X.509 certificates that have been loaded into the ".fs-verity" kernel
-keyring.  Here's an example:
+First, note that fs-verity is essentially just a way of hashing a
+file; it doesn't mandate a specific way of handling signatures.
+There are several possible ways that signatures could be handled:
+* Do it entirely in userspace
+* Use IMA appraisal (work-in-progress)
+* Use fs-verity built-in signatures
+Any such solution needs two parts: (a) a policy that determines which
+files are required to have fs-verity enabled and have a valid
+signature, and (b) enforcement of the policy.  Each part could happen
+either in a trusted userspace program(s) or in the kernel.
+fs-verity built-in signatures (which are supported when the kernel was
+built with `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`) are a hybrid
+solution where the policy of which files are required to be signed is
+determined and enforced by a trusted userspace program, but the actual
+signature verification happens in the kernel.  Specifically, with
+built-in signatures, the filesystem supports storing a signed file
+digest in each file's verity metadata.  Before allowing access to the
+file, the filesystem will automatically verify the signature against
+the set of X.509 certificates in the ".fs-verity" kernel keyring.  If
+set, the sysctl `fs.verity.require_signatures=1` will make the kernel
+enforce that every verity file has a valid built-in signature.
+fs-verity built-in signatures are primarily intended as a
+proof-of-concept; they reuse the kernel code that verifies the
+signatures of loadable kernel modules.  This solution still requires a
+trusted userspace program to enforce that particular files have
+fs-verity enabled.  Also, this solution uses PKCS#7 signatures, which
+are complex and prone to security bugs.
+Thus, if possible one of the other solutions should be used instead.
+For example, the trusted userspace program could verify signatures
+itself, using a simple signature format using a modern algorithm such
+as Ed25519.
+That being said, here are some examples of using built-in signatures:
     # Generate a new certificate and private key:
@@ -137,15 +170,6 @@
     fsverity digest file --compact --for-builtin-sig | tr -d '\n' | xxd -p -r | openssl smime -sign -in /dev/stdin ...
-By default, it's not required that verity files have a signature.
-This can be changed with `sysctl fs.verity.require_signatures=1`.
-When set, it's guaranteed that the contents of every verity file has
-been signed by one of the certificates in the keyring.
-Note: applications generally still need to check whether the file
-they're accessing really is a verity file, since an attacker could
-replace a verity file with a regular one.
 ### With IMA
 IMA support for fs-verity is planned.
diff --git a/include/libfsverity.h b/include/libfsverity.h
index fe89371..84d5f55 100644
--- a/include/libfsverity.h
+++ b/include/libfsverity.h
@@ -186,13 +186,13 @@
 			   struct libfsverity_digest **digest_ret);
- * libfsverity_sign_digest() - Sign previously computed digest of a file
- *          This signature is used by the filesystem to validate the signed file
- *          digest against a public key loaded into the .fs-verity kernel
- *          keyring, when CONFIG_FS_VERITY_BUILTIN_SIGNATURES is enabled. The
- *          signature is formatted as PKCS#7 stored in DER format. See
- *          Documentation/filesystems/fsverity.rst in the kernel source tree for
- *          further details.
+ * libfsverity_sign_digest() - Sign a file for built-in signature verification
+ *	    Sign a file digest in a way that is compatible with the Linux
+ *	    kernel's fs-verity built-in signature verification support.  The
+ *	    resulting signature will be a PKCS#7 message in DER format.  Note
+ *	    that this is not the only way to do signatures with fs-verity.  For
+ *	    more details, refer to the fsverity-utils README and to
+ *	    Documentation/filesystems/fsverity.rst in the kernel source tree.
  * @digest: pointer to previously computed digest
  * @sig_params: pointer to the certificate and private key information
  * @sig_ret: Pointer to pointer for signed digest
diff --git a/man/ b/man/
index a983912..9e565a9 100644
--- a/man/
+++ b/man/
@@ -161,6 +161,10 @@
 optionally **\-\-pkcs11-keyid**.  PKCS#11 token support is unavailable when
 fsverity-utils was built with BoringSSL rather than OpenSSL.
+**fsverity sign** should only be used if you need compatibility with fs-verity
+built-in signatures.  It is not the only way to do signatures with fs-verity.
+For more information, see the fsverity-utils README.
 Options accepted by **fsverity sign**:
diff --git a/programs/fsverity.c b/programs/fsverity.c
index 813ea2a..e4e348b 100644
--- a/programs/fsverity.c
+++ b/programs/fsverity.c
@@ -56,7 +56,7 @@
 	}, {
 		.name = "sign",
 		.func = fsverity_cmd_sign,
-		.short_desc = "Sign a file for fs-verity",
+		.short_desc = "Sign a file for fs-verity built-in signature verification",
 		.usage_str =
 "    fsverity sign FILE OUT_SIGFILE\n"
 "               [--key=KEYFILE] [--cert=CERTFILE] [--pkcs11-engine=SOFILE]\n"