1*4882a593Smuzhiyun========= 2*4882a593Smuzhiyundm-verity 3*4882a593Smuzhiyun========= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunDevice-Mapper's "verity" target provides transparent integrity checking of 6*4882a593Smuzhiyunblock devices using a cryptographic digest provided by the kernel crypto API. 7*4882a593SmuzhiyunThis target is read-only. 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunConstruction Parameters 10*4882a593Smuzhiyun======================= 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun:: 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun <version> <dev> <hash_dev> 15*4882a593Smuzhiyun <data_block_size> <hash_block_size> 16*4882a593Smuzhiyun <num_data_blocks> <hash_start_block> 17*4882a593Smuzhiyun <algorithm> <digest> <salt> 18*4882a593Smuzhiyun [<#opt_params> <opt_params>] 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun<version> 21*4882a593Smuzhiyun This is the type of the on-disk hash format. 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun 0 is the original format used in the Chromium OS. 24*4882a593Smuzhiyun The salt is appended when hashing, digests are stored continuously and 25*4882a593Smuzhiyun the rest of the block is padded with zeroes. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun 1 is the current format that should be used for new devices. 28*4882a593Smuzhiyun The salt is prepended when hashing and each digest is 29*4882a593Smuzhiyun padded with zeroes to the power of two. 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun<dev> 32*4882a593Smuzhiyun This is the device containing data, the integrity of which needs to be 33*4882a593Smuzhiyun checked. It may be specified as a path, like /dev/sdaX, or a device number, 34*4882a593Smuzhiyun <major>:<minor>. 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun<hash_dev> 37*4882a593Smuzhiyun This is the device that supplies the hash tree data. It may be 38*4882a593Smuzhiyun specified similarly to the device path and may be the same device. If the 39*4882a593Smuzhiyun same device is used, the hash_start should be outside the configured 40*4882a593Smuzhiyun dm-verity device. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun<data_block_size> 43*4882a593Smuzhiyun The block size on a data device in bytes. 44*4882a593Smuzhiyun Each block corresponds to one digest on the hash device. 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun<hash_block_size> 47*4882a593Smuzhiyun The size of a hash block in bytes. 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun<num_data_blocks> 50*4882a593Smuzhiyun The number of data blocks on the data device. Additional blocks are 51*4882a593Smuzhiyun inaccessible. You can place hashes to the same partition as data, in this 52*4882a593Smuzhiyun case hashes are placed after <num_data_blocks>. 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun<hash_start_block> 55*4882a593Smuzhiyun This is the offset, in <hash_block_size>-blocks, from the start of hash_dev 56*4882a593Smuzhiyun to the root block of the hash tree. 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun<algorithm> 59*4882a593Smuzhiyun The cryptographic hash algorithm used for this device. This should 60*4882a593Smuzhiyun be the name of the algorithm, like "sha1". 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun<digest> 63*4882a593Smuzhiyun The hexadecimal encoding of the cryptographic hash of the root hash block 64*4882a593Smuzhiyun and the salt. This hash should be trusted as there is no other authenticity 65*4882a593Smuzhiyun beyond this point. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun<salt> 68*4882a593Smuzhiyun The hexadecimal encoding of the salt value. 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun<#opt_params> 71*4882a593Smuzhiyun Number of optional parameters. If there are no optional parameters, 72*4882a593Smuzhiyun the optional paramaters section can be skipped or #opt_params can be zero. 73*4882a593Smuzhiyun Otherwise #opt_params is the number of following arguments. 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun Example of optional parameters section: 76*4882a593Smuzhiyun 1 ignore_corruption 77*4882a593Smuzhiyun 78*4882a593Smuzhiyunignore_corruption 79*4882a593Smuzhiyun Log corrupted blocks, but allow read operations to proceed normally. 80*4882a593Smuzhiyun 81*4882a593Smuzhiyunrestart_on_corruption 82*4882a593Smuzhiyun Restart the system when a corrupted block is discovered. This option is 83*4882a593Smuzhiyun not compatible with ignore_corruption and requires user space support to 84*4882a593Smuzhiyun avoid restart loops. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyunpanic_on_corruption 87*4882a593Smuzhiyun Panic the device when a corrupted block is discovered. This option is 88*4882a593Smuzhiyun not compatible with ignore_corruption and restart_on_corruption. 89*4882a593Smuzhiyun 90*4882a593Smuzhiyunignore_zero_blocks 91*4882a593Smuzhiyun Do not verify blocks that are expected to contain zeroes and always return 92*4882a593Smuzhiyun zeroes instead. This may be useful if the partition contains unused blocks 93*4882a593Smuzhiyun that are not guaranteed to contain zeroes. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyunuse_fec_from_device <fec_dev> 96*4882a593Smuzhiyun Use forward error correction (FEC) to recover from corruption if hash 97*4882a593Smuzhiyun verification fails. Use encoding data from the specified device. This 98*4882a593Smuzhiyun may be the same device where data and hash blocks reside, in which case 99*4882a593Smuzhiyun fec_start must be outside data and hash areas. 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun If the encoding data covers additional metadata, it must be accessible 102*4882a593Smuzhiyun on the hash device after the hash blocks. 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun Note: block sizes for data and hash devices must match. Also, if the 105*4882a593Smuzhiyun verity <dev> is encrypted the <fec_dev> should be too. 106*4882a593Smuzhiyun 107*4882a593Smuzhiyunfec_roots <num> 108*4882a593Smuzhiyun Number of generator roots. This equals to the number of parity bytes in 109*4882a593Smuzhiyun the encoding data. For example, in RS(M, N) encoding, the number of roots 110*4882a593Smuzhiyun is M-N. 111*4882a593Smuzhiyun 112*4882a593Smuzhiyunfec_blocks <num> 113*4882a593Smuzhiyun The number of encoding data blocks on the FEC device. The block size for 114*4882a593Smuzhiyun the FEC device is <data_block_size>. 115*4882a593Smuzhiyun 116*4882a593Smuzhiyunfec_start <offset> 117*4882a593Smuzhiyun This is the offset, in <data_block_size> blocks, from the start of the 118*4882a593Smuzhiyun FEC device to the beginning of the encoding data. 119*4882a593Smuzhiyun 120*4882a593Smuzhiyuncheck_at_most_once 121*4882a593Smuzhiyun Verify data blocks only the first time they are read from the data device, 122*4882a593Smuzhiyun rather than every time. This reduces the overhead of dm-verity so that it 123*4882a593Smuzhiyun can be used on systems that are memory and/or CPU constrained. However, it 124*4882a593Smuzhiyun provides a reduced level of security because only offline tampering of the 125*4882a593Smuzhiyun data device's content will be detected, not online tampering. 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun Hash blocks are still verified each time they are read from the hash device, 128*4882a593Smuzhiyun since verification of hash blocks is less performance critical than data 129*4882a593Smuzhiyun blocks, and a hash block will not be verified any more after all the data 130*4882a593Smuzhiyun blocks it covers have been verified anyway. 131*4882a593Smuzhiyun 132*4882a593Smuzhiyunroot_hash_sig_key_desc <key_description> 133*4882a593Smuzhiyun This is the description of the USER_KEY that the kernel will lookup to get 134*4882a593Smuzhiyun the pkcs7 signature of the roothash. The pkcs7 signature is used to validate 135*4882a593Smuzhiyun the root hash during the creation of the device mapper block device. 136*4882a593Smuzhiyun Verification of roothash depends on the config DM_VERITY_VERIFY_ROOTHASH_SIG 137*4882a593Smuzhiyun being set in the kernel. 138*4882a593Smuzhiyun 139*4882a593SmuzhiyunTheory of operation 140*4882a593Smuzhiyun=================== 141*4882a593Smuzhiyun 142*4882a593Smuzhiyundm-verity is meant to be set up as part of a verified boot path. This 143*4882a593Smuzhiyunmay be anything ranging from a boot using tboot or trustedgrub to just 144*4882a593Smuzhiyunbooting from a known-good device (like a USB drive or CD). 145*4882a593Smuzhiyun 146*4882a593SmuzhiyunWhen a dm-verity device is configured, it is expected that the caller 147*4882a593Smuzhiyunhas been authenticated in some way (cryptographic signatures, etc). 148*4882a593SmuzhiyunAfter instantiation, all hashes will be verified on-demand during 149*4882a593Smuzhiyundisk access. If they cannot be verified up to the root node of the 150*4882a593Smuzhiyuntree, the root hash, then the I/O will fail. This should detect 151*4882a593Smuzhiyuntampering with any data on the device and the hash data. 152*4882a593Smuzhiyun 153*4882a593SmuzhiyunCryptographic hashes are used to assert the integrity of the device on a 154*4882a593Smuzhiyunper-block basis. This allows for a lightweight hash computation on first read 155*4882a593Smuzhiyuninto the page cache. Block hashes are stored linearly, aligned to the nearest 156*4882a593Smuzhiyunblock size. 157*4882a593Smuzhiyun 158*4882a593SmuzhiyunIf forward error correction (FEC) support is enabled any recovery of 159*4882a593Smuzhiyuncorrupted data will be verified using the cryptographic hash of the 160*4882a593Smuzhiyuncorresponding data. This is why combining error correction with 161*4882a593Smuzhiyunintegrity checking is essential. 162*4882a593Smuzhiyun 163*4882a593SmuzhiyunHash Tree 164*4882a593Smuzhiyun--------- 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunEach node in the tree is a cryptographic hash. If it is a leaf node, the hash 167*4882a593Smuzhiyunof some data block on disk is calculated. If it is an intermediary node, 168*4882a593Smuzhiyunthe hash of a number of child nodes is calculated. 169*4882a593Smuzhiyun 170*4882a593SmuzhiyunEach entry in the tree is a collection of neighboring nodes that fit in one 171*4882a593Smuzhiyunblock. The number is determined based on block_size and the size of the 172*4882a593Smuzhiyunselected cryptographic digest algorithm. The hashes are linearly-ordered in 173*4882a593Smuzhiyunthis entry and any unaligned trailing space is ignored but included when 174*4882a593Smuzhiyuncalculating the parent node. 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunThe tree looks something like: 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun alg = sha256, num_blocks = 32768, block_size = 4096 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun:: 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun [ root ] 183*4882a593Smuzhiyun / . . . \ 184*4882a593Smuzhiyun [entry_0] [entry_1] 185*4882a593Smuzhiyun / . . . \ . . . \ 186*4882a593Smuzhiyun [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] 187*4882a593Smuzhiyun / ... \ / . . . \ / \ 188*4882a593Smuzhiyun blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun 191*4882a593SmuzhiyunOn-disk format 192*4882a593Smuzhiyun============== 193*4882a593Smuzhiyun 194*4882a593SmuzhiyunThe verity kernel code does not read the verity metadata on-disk header. 195*4882a593SmuzhiyunIt only reads the hash blocks which directly follow the header. 196*4882a593SmuzhiyunIt is expected that a user-space tool will verify the integrity of the 197*4882a593Smuzhiyunverity header. 198*4882a593Smuzhiyun 199*4882a593SmuzhiyunAlternatively, the header can be omitted and the dmsetup parameters can 200*4882a593Smuzhiyunbe passed via the kernel command-line in a rooted chain of trust where 201*4882a593Smuzhiyunthe command-line is verified. 202*4882a593Smuzhiyun 203*4882a593SmuzhiyunDirectly following the header (and with sector number padded to the next hash 204*4882a593Smuzhiyunblock boundary) are the hash blocks which are stored a depth at a time 205*4882a593Smuzhiyun(starting from the root), sorted in order of increasing index. 206*4882a593Smuzhiyun 207*4882a593SmuzhiyunThe full specification of kernel parameters and on-disk metadata format 208*4882a593Smuzhiyunis available at the cryptsetup project's wiki page 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity 211*4882a593Smuzhiyun 212*4882a593SmuzhiyunStatus 213*4882a593Smuzhiyun====== 214*4882a593SmuzhiyunV (for Valid) is returned if every check performed so far was valid. 215*4882a593SmuzhiyunIf any check failed, C (for Corruption) is returned. 216*4882a593Smuzhiyun 217*4882a593SmuzhiyunExample 218*4882a593Smuzhiyun======= 219*4882a593SmuzhiyunSet up a device:: 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun # dmsetup create vroot --readonly --table \ 222*4882a593Smuzhiyun "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ 223*4882a593Smuzhiyun "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ 224*4882a593Smuzhiyun "1234000000000000000000000000000000000000000000000000000000000000" 225*4882a593Smuzhiyun 226*4882a593SmuzhiyunA command line tool veritysetup is available to compute or verify 227*4882a593Smuzhiyunthe hash tree or activate the kernel device. This is available from 228*4882a593Smuzhiyunthe cryptsetup upstream repository https://gitlab.com/cryptsetup/cryptsetup/ 229*4882a593Smuzhiyun(as a libcryptsetup extension). 230*4882a593Smuzhiyun 231*4882a593SmuzhiyunCreate hash on the device:: 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun # veritysetup format /dev/sda1 /dev/sda2 234*4882a593Smuzhiyun ... 235*4882a593Smuzhiyun Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 236*4882a593Smuzhiyun 237*4882a593SmuzhiyunActivate the device:: 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun # veritysetup create vroot /dev/sda1 /dev/sda2 \ 240*4882a593Smuzhiyun 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 241