1# fsverity-utils 2 3## Introduction 4 5This is fsverity-utils, a set of userspace utilities for fs-verity. 6fs-verity is a Linux kernel feature that does transparent on-demand 7integrity/authenticity verification of the contents of read-only 8files, using a hidden Merkle tree (hash tree) associated with the 9file. It is similar to dm-verity, but implemented at the file level 10rather than at the block device level. See the [kernel 11documentation](https://www.kernel.org/doc/html/latest/filesystems/fsverity.html) 12for more information about fs-verity, including which filesystems 13support it. 14 15fsverity-utils currently contains just one program, `fsverity`. The 16`fsverity` program allows you to set up fs-verity protected files. 17In addition, the file digest computation and signing functionality of 18`fsverity` is optionally exposed through a C library `libfsverity`. 19See `libfsverity.h` for the API of this library. 20 21## Building and installing 22 23To build fsverity-utils, first install the needed build dependencies. For 24example, on Debian-based systems, run: 25 26```bash 27 sudo apt-get install libssl-dev 28``` 29 30OpenSSL must be version 1.0.0 or later. This is the only runtime dependency. 31 32Then, to build and install fsverity-utils: 33 34```bash 35 make 36 sudo make install 37``` 38 39By default, the following targets are built and installed: the program 40`fsverity`, the static library `libfsverity.a`, the shared library 41`libfsverity.so`, and the manual page `fsverity.1`. You can also run 42`make check` to build and run the tests, or `make help` to display all 43available build targets. 44 45By default, `fsverity` is statically linked to `libfsverity`. You can 46use `make USE_SHARED_LIB=1` to use dynamic linking instead. 47 48See the `Makefile` for other supported build and installation options. 49 50### Building on Windows 51 52There is minimal support for building Windows executables using MinGW. 53```bash 54 make CC=x86_64-w64-mingw32-gcc 55``` 56 57`fsverity.exe` will be built, and it supports the `digest` and `sign` commands. 58 59A Windows build of OpenSSL/libcrypto needs to be available. 60 61## Examples 62 63Full usage information for `fsverity` can be found in the manual page 64(`man fsverity`). Here, we just show some typical examples. 65 66### Basic use 67 68```bash 69 mkfs.ext4 -O verity /dev/vdc 70 mount /dev/vdc /vdc 71 cd /vdc 72 73 # Create a test file 74 head -c 1000000 /dev/urandom > file 75 sha256sum file 76 77 # Enable verity on the file 78 fsverity enable file 79 80 # Show the verity file digest 81 fsverity measure file 82 83 # File should still be readable as usual. However, all data read 84 # is now transparently checked against a hidden Merkle tree, whose 85 # root hash is incorporated into the verity file digest. Reads of 86 # any corrupted parts of the data will fail. 87 sha256sum file 88``` 89 90Note that in the above example, the file isn't signed. Therefore, to 91get any authenticity protection (as opposed to just integrity 92protection), the output of `fsverity measure` needs to be compared 93against a trusted value. 94 95### With IMA 96 97Since Linux v5.19, the kernel's IMA (Integrity Measurement 98Architecture) subsystem supports using fs-verity file digests in lieu 99of traditional file digests. This must be configured in the IMA 100policy. For more information, see the IMA documentation. 101 102### Using builtin signatures 103 104First, note that fs-verity is essentially just a way of hashing a 105file; it doesn't mandate a specific way of handling signatures. 106There are several possible ways that signatures could be handled: 107 108* Do it entirely in userspace 109* Use IMA appraisal 110* Use fs-verity built-in signatures 111 112Any such solution needs two parts: (a) a policy that determines which 113files are required to have fs-verity enabled and have a valid 114signature, and (b) enforcement of the policy. Each part could happen 115either in a trusted userspace program(s) or in the kernel. 116 117fs-verity built-in signatures (which are supported when the kernel was 118built with `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`) are a hybrid 119solution where the policy of which files are required to be signed is 120determined and enforced by a trusted userspace program, but the actual 121signature verification happens in the kernel. Specifically, with 122built-in signatures, the filesystem supports storing a signed file 123digest in each file's verity metadata. Before allowing access to the 124file, the filesystem will automatically verify the signature against 125the set of X.509 certificates in the ".fs-verity" kernel keyring. If 126set, the sysctl `fs.verity.require_signatures=1` will make the kernel 127enforce that every verity file has a valid built-in signature. 128 129fs-verity built-in signatures are primarily intended as a 130proof-of-concept; they reuse the kernel code that verifies the 131signatures of loadable kernel modules. This solution still requires a 132trusted userspace program to enforce that particular files have 133fs-verity enabled. Also, this solution uses PKCS#7 signatures, which 134are complex and prone to security bugs. 135 136Thus, if possible one of the other solutions should be used instead. 137For example, the trusted userspace program could verify signatures 138itself, using a simple signature format using a modern algorithm such 139as Ed25519. 140 141That being said, here are some examples of using built-in signatures: 142 143```bash 144 # Generate a new certificate and private key: 145 openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -out cert.pem 146 147 # Convert the certificate from PEM to DER format: 148 openssl x509 -in cert.pem -out cert.der -outform der 149 150 # Load the certificate into the fs-verity keyring: 151 keyctl padd asymmetric '' %keyring:.fs-verity < cert.der 152 153 # Optionally, lock the keyring so that no more keys can be added 154 # (requires keyctl v1.5.11 or later): 155 keyctl restrict_keyring %keyring:.fs-verity 156 157 # Optionally, require that all verity files be signed: 158 sysctl fs.verity.require_signatures=1 159 160 # Now set up fs-verity on a test file: 161 sha256sum file 162 fsverity sign file file.sig --key=key.pem --cert=cert.pem 163 fsverity enable file --signature=file.sig 164 rm -f file.sig 165 sha256sum file 166 167 # The digest to be signed can also be printed separately, hex 168 # encoded, in case the integrated signing cannot be used: 169 fsverity digest file --compact --for-builtin-sig | tr -d '\n' | xxd -p -r | openssl smime -sign -in /dev/stdin ... 170``` 171 172## Notices 173 174fsverity-utils is provided under the terms of the MIT license. A copy 175of this license can be found in the file named [LICENSE](LICENSE). 176 177Send questions and bug reports to [email protected]. 178 179Signed release tarballs for fsverity-utils can be found on 180[kernel.org](https://kernel.org/pub/linux/kernel/people/ebiggers/fsverity-utils/). 181 182## Contributing 183 184Send patches to [email protected] with the additional tag 185`fsverity-utils` in the subject, i.e. `[fsverity-utils PATCH]`. 186Patches should follow the Linux kernel's coding style. A 187`.clang-format` file is provided to approximate this coding style; 188consider using `git clang-format`. Additionally, like the Linux 189kernel itself, patches require the following "sign-off" procedure: 190 191The sign-off is a simple line at the end of the explanation for the 192patch, which certifies that you wrote it or otherwise have the right 193to pass it on as an open-source patch. The rules are pretty simple: 194if you can certify the below: 195 196Developer's Certificate of Origin 1.1 197 198By making a contribution to this project, I certify that: 199 200 (a) The contribution was created in whole or in part by me and I 201 have the right to submit it under the open source license 202 indicated in the file; or 203 204 (b) The contribution is based upon previous work that, to the best 205 of my knowledge, is covered under an appropriate open source 206 license and I have the right under that license to submit that 207 work with modifications, whether created in whole or in part 208 by me, under the same open source license (unless I am 209 permitted to submit under a different license), as indicated 210 in the file; or 211 212 (c) The contribution was provided directly to me by some other 213 person who certified (a), (b) or (c) and I have not modified 214 it. 215 216 (d) I understand and agree that this project and the contribution 217 are public and that a record of the contribution (including all 218 personal information I submit with it, including my sign-off) is 219 maintained indefinitely and may be redistributed consistent with 220 this project or the open source license(s) involved. 221 222then you just add a line saying:: 223 224 Signed-off-by: Random J Developer <[email protected]> 225 226using your real name (sorry, no pseudonyms or anonymous contributions.) 227