# Introduction
This is `fsverity`, a userspace utility for fs-verity. fs-verity is
a Linux kernel feature that does transparent on-demand
integrity/authenticity verification of the contents of read-only
files, using a Merkle tree (hash tree) hidden after the end of the
file. The mechanism is similar to dm-verity, but implemented at the
file level rather than at the block device level. The `fsverity`
utility allows you to set up fs-verity protected files.
fs-verity will initially be supported by the ext4 and f2fs
filesystems, but it may later be supported by other filesystems too.
# Building and installing
The `fsverity` utility uses the OpenSSL library, so you first must
install the needed development files. For example, on Debian-based
systems, run:
```bash
sudo apt-get install libssl-dev
```
OpenSSL must be version 1.0.0 or later.
Then, to build and install:
```bash
make
sudo make install
```
# Examples
## Basic use
```bash
mkfs.f2fs -O verity /dev/vdc
mount /dev/vdc /vdc
cd /vdc
# Create a test file
head -c 1000000 /dev/urandom > file
md5sum file
# Append the Merkle tree and other metadata to the file:
fsverity setup file
# Enable fs-verity on the file
fsverity enable file
# Should show the same hash that 'fsverity setup' printed.
# This hash can be logged, or compared to a trusted value.
fsverity measure file
# Contents are now transparently verified and should match the
# original file contents, i.e. the metadata is hidden.
md5sum file
```
Note that in the above example, the file isn't signed. Therefore, to
get any authenticity protection (as opposed to just integrity
protection), the output of `fsverity measure` needs to be compared
against a trusted value.
## Using builtin signatures
With `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`, the filesystem supports
automatically verifying a signed file measurement that has been
included in the fs-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:
```bash
# Generate a new certificate and private key:
openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -out cert.pem
# Convert the certificate from PEM to DER format:
openssl x509 -in cert.pem -out cert.der -outform der
# Load the certificate into the fs-verity keyring:
keyctl padd asymmetric '' %keyring:.fs-verity < cert.der
# Optionally, lock the keyring so that no more keys can be added
# (requires keyctl v1.5.11 or later):
keyctl restrict_keyring %keyring:.fs-verity
# Optionally, require that all fs-verity files be signed:
sysctl fs.verity.require_signatures=1
# Now set up fs-verity on a test file:
md5sum file
fsverity setup file --signing-key=key.pem --signing-cert=cert.pem
fsverity enable file
md5sum file
```
By default, it's not required that fs-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 fs-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 fs-verity file, since an attacker could
replace a fs-verity file with a regular one.
## With IMA
IMA support for fs-verity is planned.
# Notices
This project is provided under the terms of the GNU General Public
License, version 2; or at your option, any later version. A copy of the
GPLv2 can be found in the file named [COPYING](COPYING).
Permission to link to OpenSSL (libcrypto) is granted.
Send questions and bug reports to linux-fscrypt@vger.kernel.org.
# Submitting patches
Send patches to linux-fscrypt@vger.kernel.org. Patches should follow
the Linux kernel's coding style. Additionally, like the Linux kernel
itself, patches require the following "sign-off" procedure:
The sign-off is a simple line at the end of the explanation for the
patch, which certifies that you wrote it or otherwise have the right
to pass it on as an open-source patch. The rules are pretty simple:
if you can certify the below:
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
then you just add a line saying::
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name (sorry, no pseudonyms or anonymous contributions.)