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