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