dm: verity target
Subsystems (3)
PATCH 1/1 dm: verity target
The verity target provides transparent integrity checking of block devices using a cryptographic digest.
dm-verity is meant to be setup as part of a verified boot path. This may be anything ranging from a boot using tboot or trustedgrub to just booting from a known-good device (like a USB drive or CD).
dm-verity is part of ChromeOS's verified boot path. It is used to verify the integrity of the root filesystem on boot. The root filesystem is mounted on a dm-verity partition which transparently verifies each block with a bootloader verified hash passed into the kernel at boot.
Changes in V7:
* https://lkml.org/lkml/2012/3/8/454 (Mikulas Patocka)
* Reported bug: can't assume workqueue's don't migrate CPUs.
* https://lkml.org/lkml/2012/3/9/580 (Tejun Heo)
* Suggested fixing by flushing workqueue in hotcpu notifier.
Changes in V6:
* Fixed bug in rmmod. Was freeing the same object NR_CPUS times.
* Fixed example in documentation.
Changes in V5:
* https://lkml.org/lkml/2012/2/29/421 (Mikulas Patocka)
* Fixed off-by-one error.
* Added support for filesystems bigger than 4G (bug fix).
* https://lkml.org/lkml/2012/2/29/426 (Andrew Morton)
* Fixed checkpatch errors/warning.
* Made code cpu-hotplug-aware.
* Remove NULL check before calling kfree.
* No longer checking __GFP_WAIT allocations.
* Propogate io->error instead of always EIO.
* Remove unneeded and undesirable casts of void.
* Use DMERR_LIMIT on io errors to avoid spamming dmesg.
* Flush workqueue on rmmod.
Changes in V4:
* Discussion over phone (Alasdair G Kergon)
* copy _ioctl fix from dm-linear
* verity_status format fixes to match dm conventions
* s/dm-bht/verity_tree
* put everything into dm-verity.c
* ctr changed to dm conventions
* use hex2bin
* use conventional dm names for function
* s/dm_//
* for example: verity_ctr versus dm_verity_ctr
* use per_cpu API
Changes in V3:
* Discussion over irc (Alasdair G Kergon)
* Implement ioctl hook
Changes in V2:
* https://lkml.org/lkml/2011/11/10/85 (Steffen Klassert)
* Use shash API instead of older hash API
--- Documentation/device-mapper/verity.txt | 151 ++++ drivers/md/Kconfig | 16 + drivers/md/Makefile | 1 + drivers/md/dm-verity.c | 1390 ++++++++++++++++++++++++++++++++ 4 files changed, 1558 insertions(+), 0 deletions(-) create mode 100644 Documentation/device-mapper/verity.txt create mode 100644 drivers/md/dm-verity.c
Documentation/device-mapper/verity.txt new file +151 -0
@@ -0,0 +1,151 @@ +dm-verity +========== + +Device-Mapper's "verity" target provides transparent integrity checking of +block devices using a cryptographic digest provided by the kernel crypto API. +This target is read-only. + +Parameters: + <version> <dev> <hash_dev> <hash_start> <block_size> <alg> <digest> <salt> + +<version> + This is the version number of the on-disk format. Currently, there is + only version 0. + +<dev> + This is the device that is going to be integrity checked. It may be + a subset of the full device as specified to dmsetup (start sector and count) + It may be specified as a path, like /dev/sdaX, or a device number, + <major>:<minor>. + +<hash_dev> + This is the device that that supplies the hash tree data. It may be + specified similarly to the device path and may be the same device. If the + same device is used, the hash offset should be outside of the dm-verity + configured device size. + +<hash_start> + This is the offset, in 512-byte sectors, from the start of hash_dev to + the root block of the hash tree. + +<block_size> + The size of a hash block. Also, the size of a block to be hashed. + +<alg> + The cryptographic hash algorithm used for this device. This should + be the name of the algorithm, like "sha1". + +<digest> + The hexadecimal encoding of the cryptographic hash of all of the + neighboring nodes at the first level of the tree. This hash should be + trusted as there is no other authenticity beyond this point. + +<salt> + The hexadecimal encoding of the salt value. + +Theory of operation +=================== + +dm-verity is meant to be setup as part of a verified boot path. This +may be anything ranging from a boot using tboot or trustedgrub to just +booting from a known-good device (like a USB drive or CD). + +When a dm-verity device is configured, it is expected that the caller +has been authenticated in some way (cryptographic signatures, etc). +After instantiation, all hashes will be verified on-demand during +disk access. If they cannot be verified up to the root node of the +tree, the root hash, then the I/O will fail. This should identify +tampering with any data on the device and the hash data. + +Cryptographic hashes are used to assert the integrity of the device on a +per-block basis. This allows for a lightweight hash computation on first read +into the page cache. Block hashes are stored linearly aligned to the nearest +block the size of a page. + +Hash Tree +--------- + +Each node in the tree is a cryptographic hash. If it is a leaf node, the hash +is of some block data on disk. If it is an intermediary node, then the hash is +of a number of child nodes. + +Each entry in the tree is a collection of neighboring nodes that fit in one +block. The number is determined based on block_size and the size of the +selected cryptographic digest algorithm. The hashes are linearly ordered in +this entry and any unaligned trailing space is ignored but included when +calculating the parent node. + +The tree looks something like: + +alg = sha256, num_blocks = 32768, block_size = 4096 + + [ root ] + / . . . \ + [entry_0] [entry_1] + / . . . \ . . . \ + [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] + / ... \ / . . . \ / \ + blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767 + +On-disk format +============== + +Below is the recommended on-disk format. The verity kernel code does not +read the on-disk header. It only reads the hash blocks which directly +follow the header. It is expected that a user-space tool will verify the +integrity of the verity_header and then call dm_setup with the correct +parameters. Alternatively, the header can be omitted and the dm_setup +parameters can be passed via the kernel command-line in a rooted chain +of trust where the command-line is verified. + +The on-disk format is especially useful in cases where the hash blocks +are on a separate partition. The magic number allows easy identification +of the partition contents. Alternatively, the hash blocks can be stored +in the same partition as the data to be verified. In such a configuration +the filesystem on the partition would be sized a little smaller than +the full-partition, leaving room for the hash blocks. + +struct verity_header { + uint64_t magic = 0x7665726974790a00; + uint32_t version; + uint32_t block_size; + char digest[128]; /* in hex-ascii, null-terminated or 128-bytes */ + char salt[128]; /* in hex-ascii, null-terminated or 128-bytes */ +} + +struct verity_header_block { + struct verity_header; + char unused[block_size - sizeof(struct verity_header) - sizeof(sig)]; + char sig[128]; /* in hex-ascii, null-terminated or 128-bytes */ +} + +Directly following the header are the hash blocks which are stored a depth +at a time (starting from the root), sorted in order of increasing index. + +Usage +===== + +The API provides mechanisms for reading and verifying a tree. When reading, all +required data for the hash tree should be populated for a block before +attempting a verify. This can be done by calling dm_bht_populate(). When all +data is ready, a call to dm_bht_verify_block() with the expected hash value will +perform both the direct block hash check and the hashes of the parent and +neighboring nodes where needed to ensure validity up to the root hash. Note, +dm_bht_set_root_hexdigest() should be called before any verification attempts +occur. + +Example +======= + +Setup a device; +[[ + dmsetup create vroot --table \ + "0 `blockdev --getsize /dev/sda1` "\ + "verity /dev/sda1 /dev/sda2 0 4096 sha256 "\ + "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ + "1234000000000000000000000000000000000000000000000000000000000000" +]] + +A command line tool is available to compute the hash tree and return the +root hash value. + http://git.chromium.org/cgi-bin/gitweb.cgi?p=dm-verity.git;a=tree
drivers/md/Kconfig +16 -0
@@ -370,4 +370,20 @@ config DM_FLAKEY ---help--- A target that intermittently fails I/O for debugging purposes. +config DM_VERITY + tristate "Verity target support" + depends on BLK_DEV_DM + select CRYPTO + select CRYPTO_HASH + ---help--- + This device-mapper target allows you to create a device that + transparently integrity checks the data on it. You'll need to + activate the digests you're going to use in the cryptoapi + configuration. + + To compile this code as a module, choose M here: the module will + be called dm-verity. + + If unsure, say N. + endif # MD
drivers/md/Makefile +1 -0
@@ -39,6 +39,7 @@ obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/ obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o +obj-$(CONFIG_DM_VERITY) += dm-verity.o obj-$(CONFIG_DM_ZERO) += dm-zero.o obj-$(CONFIG_DM_RAID) += dm-raid.o obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o
drivers/md/dm-verity.c new file +1390 -0
1,390 lines not on this page · raw message
Signature · 1 line
1.7.7.3