16cf2a73cSMauro Carvalho Chehab========= 26cf2a73cSMauro Carvalho Chehabdm-verity 36cf2a73cSMauro Carvalho Chehab========= 46cf2a73cSMauro Carvalho Chehab 56cf2a73cSMauro Carvalho ChehabDevice-Mapper's "verity" target provides transparent integrity checking of 66cf2a73cSMauro Carvalho Chehabblock devices using a cryptographic digest provided by the kernel crypto API. 76cf2a73cSMauro Carvalho ChehabThis target is read-only. 86cf2a73cSMauro Carvalho Chehab 96cf2a73cSMauro Carvalho ChehabConstruction Parameters 106cf2a73cSMauro Carvalho Chehab======================= 116cf2a73cSMauro Carvalho Chehab 126cf2a73cSMauro Carvalho Chehab:: 136cf2a73cSMauro Carvalho Chehab 146cf2a73cSMauro Carvalho Chehab <version> <dev> <hash_dev> 156cf2a73cSMauro Carvalho Chehab <data_block_size> <hash_block_size> 166cf2a73cSMauro Carvalho Chehab <num_data_blocks> <hash_start_block> 176cf2a73cSMauro Carvalho Chehab <algorithm> <digest> <salt> 186cf2a73cSMauro Carvalho Chehab [<#opt_params> <opt_params>] 196cf2a73cSMauro Carvalho Chehab 206cf2a73cSMauro Carvalho Chehab<version> 216cf2a73cSMauro Carvalho Chehab This is the type of the on-disk hash format. 226cf2a73cSMauro Carvalho Chehab 236cf2a73cSMauro Carvalho Chehab 0 is the original format used in the Chromium OS. 246cf2a73cSMauro Carvalho Chehab The salt is appended when hashing, digests are stored continuously and 256cf2a73cSMauro Carvalho Chehab the rest of the block is padded with zeroes. 266cf2a73cSMauro Carvalho Chehab 276cf2a73cSMauro Carvalho Chehab 1 is the current format that should be used for new devices. 286cf2a73cSMauro Carvalho Chehab The salt is prepended when hashing and each digest is 296cf2a73cSMauro Carvalho Chehab padded with zeroes to the power of two. 306cf2a73cSMauro Carvalho Chehab 316cf2a73cSMauro Carvalho Chehab<dev> 326cf2a73cSMauro Carvalho Chehab This is the device containing data, the integrity of which needs to be 336cf2a73cSMauro Carvalho Chehab checked. It may be specified as a path, like /dev/sdaX, or a device number, 346cf2a73cSMauro Carvalho Chehab <major>:<minor>. 356cf2a73cSMauro Carvalho Chehab 366cf2a73cSMauro Carvalho Chehab<hash_dev> 376cf2a73cSMauro Carvalho Chehab This is the device that supplies the hash tree data. It may be 386cf2a73cSMauro Carvalho Chehab specified similarly to the device path and may be the same device. If the 396cf2a73cSMauro Carvalho Chehab same device is used, the hash_start should be outside the configured 406cf2a73cSMauro Carvalho Chehab dm-verity device. 416cf2a73cSMauro Carvalho Chehab 426cf2a73cSMauro Carvalho Chehab<data_block_size> 436cf2a73cSMauro Carvalho Chehab The block size on a data device in bytes. 446cf2a73cSMauro Carvalho Chehab Each block corresponds to one digest on the hash device. 456cf2a73cSMauro Carvalho Chehab 466cf2a73cSMauro Carvalho Chehab<hash_block_size> 476cf2a73cSMauro Carvalho Chehab The size of a hash block in bytes. 486cf2a73cSMauro Carvalho Chehab 496cf2a73cSMauro Carvalho Chehab<num_data_blocks> 506cf2a73cSMauro Carvalho Chehab The number of data blocks on the data device. Additional blocks are 516cf2a73cSMauro Carvalho Chehab inaccessible. You can place hashes to the same partition as data, in this 526cf2a73cSMauro Carvalho Chehab case hashes are placed after <num_data_blocks>. 536cf2a73cSMauro Carvalho Chehab 546cf2a73cSMauro Carvalho Chehab<hash_start_block> 556cf2a73cSMauro Carvalho Chehab This is the offset, in <hash_block_size>-blocks, from the start of hash_dev 566cf2a73cSMauro Carvalho Chehab to the root block of the hash tree. 576cf2a73cSMauro Carvalho Chehab 586cf2a73cSMauro Carvalho Chehab<algorithm> 596cf2a73cSMauro Carvalho Chehab The cryptographic hash algorithm used for this device. This should 606cf2a73cSMauro Carvalho Chehab be the name of the algorithm, like "sha1". 616cf2a73cSMauro Carvalho Chehab 626cf2a73cSMauro Carvalho Chehab<digest> 636cf2a73cSMauro Carvalho Chehab The hexadecimal encoding of the cryptographic hash of the root hash block 646cf2a73cSMauro Carvalho Chehab and the salt. This hash should be trusted as there is no other authenticity 656cf2a73cSMauro Carvalho Chehab beyond this point. 666cf2a73cSMauro Carvalho Chehab 676cf2a73cSMauro Carvalho Chehab<salt> 686cf2a73cSMauro Carvalho Chehab The hexadecimal encoding of the salt value. 696cf2a73cSMauro Carvalho Chehab 706cf2a73cSMauro Carvalho Chehab<#opt_params> 716cf2a73cSMauro Carvalho Chehab Number of optional parameters. If there are no optional parameters, 72751d5b27SAndrew Klychkov the optional parameters section can be skipped or #opt_params can be zero. 736cf2a73cSMauro Carvalho Chehab Otherwise #opt_params is the number of following arguments. 746cf2a73cSMauro Carvalho Chehab 756cf2a73cSMauro Carvalho Chehab Example of optional parameters section: 766cf2a73cSMauro Carvalho Chehab 1 ignore_corruption 776cf2a73cSMauro Carvalho Chehab 786cf2a73cSMauro Carvalho Chehabignore_corruption 796cf2a73cSMauro Carvalho Chehab Log corrupted blocks, but allow read operations to proceed normally. 806cf2a73cSMauro Carvalho Chehab 816cf2a73cSMauro Carvalho Chehabrestart_on_corruption 826cf2a73cSMauro Carvalho Chehab Restart the system when a corrupted block is discovered. This option is 836cf2a73cSMauro Carvalho Chehab not compatible with ignore_corruption and requires user space support to 846cf2a73cSMauro Carvalho Chehab avoid restart loops. 856cf2a73cSMauro Carvalho Chehab 86e1fef0b0SJeongHyeon Leepanic_on_corruption 87e1fef0b0SJeongHyeon Lee Panic the device when a corrupted block is discovered. This option is 88e1fef0b0SJeongHyeon Lee not compatible with ignore_corruption and restart_on_corruption. 89e1fef0b0SJeongHyeon Lee 906cf2a73cSMauro Carvalho Chehabignore_zero_blocks 916cf2a73cSMauro Carvalho Chehab Do not verify blocks that are expected to contain zeroes and always return 926cf2a73cSMauro Carvalho Chehab zeroes instead. This may be useful if the partition contains unused blocks 936cf2a73cSMauro Carvalho Chehab that are not guaranteed to contain zeroes. 946cf2a73cSMauro Carvalho Chehab 956cf2a73cSMauro Carvalho Chehabuse_fec_from_device <fec_dev> 966cf2a73cSMauro Carvalho Chehab Use forward error correction (FEC) to recover from corruption if hash 976cf2a73cSMauro Carvalho Chehab verification fails. Use encoding data from the specified device. This 986cf2a73cSMauro Carvalho Chehab may be the same device where data and hash blocks reside, in which case 996cf2a73cSMauro Carvalho Chehab fec_start must be outside data and hash areas. 1006cf2a73cSMauro Carvalho Chehab 1016cf2a73cSMauro Carvalho Chehab If the encoding data covers additional metadata, it must be accessible 1026cf2a73cSMauro Carvalho Chehab on the hash device after the hash blocks. 1036cf2a73cSMauro Carvalho Chehab 1046cf2a73cSMauro Carvalho Chehab Note: block sizes for data and hash devices must match. Also, if the 1056cf2a73cSMauro Carvalho Chehab verity <dev> is encrypted the <fec_dev> should be too. 1066cf2a73cSMauro Carvalho Chehab 1076cf2a73cSMauro Carvalho Chehabfec_roots <num> 1086cf2a73cSMauro Carvalho Chehab Number of generator roots. This equals to the number of parity bytes in 1096cf2a73cSMauro Carvalho Chehab the encoding data. For example, in RS(M, N) encoding, the number of roots 1106cf2a73cSMauro Carvalho Chehab is M-N. 1116cf2a73cSMauro Carvalho Chehab 1126cf2a73cSMauro Carvalho Chehabfec_blocks <num> 1136cf2a73cSMauro Carvalho Chehab The number of encoding data blocks on the FEC device. The block size for 1146cf2a73cSMauro Carvalho Chehab the FEC device is <data_block_size>. 1156cf2a73cSMauro Carvalho Chehab 1166cf2a73cSMauro Carvalho Chehabfec_start <offset> 1176cf2a73cSMauro Carvalho Chehab This is the offset, in <data_block_size> blocks, from the start of the 1186cf2a73cSMauro Carvalho Chehab FEC device to the beginning of the encoding data. 1196cf2a73cSMauro Carvalho Chehab 1206cf2a73cSMauro Carvalho Chehabcheck_at_most_once 1216cf2a73cSMauro Carvalho Chehab Verify data blocks only the first time they are read from the data device, 1226cf2a73cSMauro Carvalho Chehab rather than every time. This reduces the overhead of dm-verity so that it 1236cf2a73cSMauro Carvalho Chehab can be used on systems that are memory and/or CPU constrained. However, it 1246cf2a73cSMauro Carvalho Chehab provides a reduced level of security because only offline tampering of the 1256cf2a73cSMauro Carvalho Chehab data device's content will be detected, not online tampering. 1266cf2a73cSMauro Carvalho Chehab 1276cf2a73cSMauro Carvalho Chehab Hash blocks are still verified each time they are read from the hash device, 1286cf2a73cSMauro Carvalho Chehab since verification of hash blocks is less performance critical than data 1296cf2a73cSMauro Carvalho Chehab blocks, and a hash block will not be verified any more after all the data 1306cf2a73cSMauro Carvalho Chehab blocks it covers have been verified anyway. 1316cf2a73cSMauro Carvalho Chehab 13288cd3e6cSJaskaran Khuranaroot_hash_sig_key_desc <key_description> 13388cd3e6cSJaskaran Khurana This is the description of the USER_KEY that the kernel will lookup to get 13488cd3e6cSJaskaran Khurana the pkcs7 signature of the roothash. The pkcs7 signature is used to validate 13588cd3e6cSJaskaran Khurana the root hash during the creation of the device mapper block device. 13688cd3e6cSJaskaran Khurana Verification of roothash depends on the config DM_VERITY_VERIFY_ROOTHASH_SIG 1374da8f8c8SMickaël Salaün being set in the kernel. The signatures are checked against the builtin 1384da8f8c8SMickaël Salaün trusted keyring by default, or the secondary trusted keyring if 1394da8f8c8SMickaël Salaün DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING is set. The secondary 1404da8f8c8SMickaël Salaün trusted keyring includes by default the builtin trusted keyring, and it can 1414da8f8c8SMickaël Salaün also gain new certificates at run time if they are signed by a certificate 1424da8f8c8SMickaël Salaün already in the secondary trusted keyring. 14388cd3e6cSJaskaran Khurana 144*dc3efedfSMilan Broztry_verify_in_tasklet 145*dc3efedfSMilan Broz If verity hashes are in cache, verify data blocks in kernel tasklet instead 146*dc3efedfSMilan Broz of workqueue. This option can reduce IO latency. 147*dc3efedfSMilan Broz 1486cf2a73cSMauro Carvalho ChehabTheory of operation 1496cf2a73cSMauro Carvalho Chehab=================== 1506cf2a73cSMauro Carvalho Chehab 1516cf2a73cSMauro Carvalho Chehabdm-verity is meant to be set up as part of a verified boot path. This 1526cf2a73cSMauro Carvalho Chehabmay be anything ranging from a boot using tboot or trustedgrub to just 1536cf2a73cSMauro Carvalho Chehabbooting from a known-good device (like a USB drive or CD). 1546cf2a73cSMauro Carvalho Chehab 1556cf2a73cSMauro Carvalho ChehabWhen a dm-verity device is configured, it is expected that the caller 1566cf2a73cSMauro Carvalho Chehabhas been authenticated in some way (cryptographic signatures, etc). 1576cf2a73cSMauro Carvalho ChehabAfter instantiation, all hashes will be verified on-demand during 1586cf2a73cSMauro Carvalho Chehabdisk access. If they cannot be verified up to the root node of the 1596cf2a73cSMauro Carvalho Chehabtree, the root hash, then the I/O will fail. This should detect 1606cf2a73cSMauro Carvalho Chehabtampering with any data on the device and the hash data. 1616cf2a73cSMauro Carvalho Chehab 1626cf2a73cSMauro Carvalho ChehabCryptographic hashes are used to assert the integrity of the device on a 1636cf2a73cSMauro Carvalho Chehabper-block basis. This allows for a lightweight hash computation on first read 1646cf2a73cSMauro Carvalho Chehabinto the page cache. Block hashes are stored linearly, aligned to the nearest 1656cf2a73cSMauro Carvalho Chehabblock size. 1666cf2a73cSMauro Carvalho Chehab 1676cf2a73cSMauro Carvalho ChehabIf forward error correction (FEC) support is enabled any recovery of 1686cf2a73cSMauro Carvalho Chehabcorrupted data will be verified using the cryptographic hash of the 1696cf2a73cSMauro Carvalho Chehabcorresponding data. This is why combining error correction with 1706cf2a73cSMauro Carvalho Chehabintegrity checking is essential. 1716cf2a73cSMauro Carvalho Chehab 1726cf2a73cSMauro Carvalho ChehabHash Tree 1736cf2a73cSMauro Carvalho Chehab--------- 1746cf2a73cSMauro Carvalho Chehab 1756cf2a73cSMauro Carvalho ChehabEach node in the tree is a cryptographic hash. If it is a leaf node, the hash 1766cf2a73cSMauro Carvalho Chehabof some data block on disk is calculated. If it is an intermediary node, 1776cf2a73cSMauro Carvalho Chehabthe hash of a number of child nodes is calculated. 1786cf2a73cSMauro Carvalho Chehab 1796cf2a73cSMauro Carvalho ChehabEach entry in the tree is a collection of neighboring nodes that fit in one 1806cf2a73cSMauro Carvalho Chehabblock. The number is determined based on block_size and the size of the 1816cf2a73cSMauro Carvalho Chehabselected cryptographic digest algorithm. The hashes are linearly-ordered in 1826cf2a73cSMauro Carvalho Chehabthis entry and any unaligned trailing space is ignored but included when 1836cf2a73cSMauro Carvalho Chehabcalculating the parent node. 1846cf2a73cSMauro Carvalho Chehab 1856cf2a73cSMauro Carvalho ChehabThe tree looks something like: 1866cf2a73cSMauro Carvalho Chehab 1876cf2a73cSMauro Carvalho Chehab alg = sha256, num_blocks = 32768, block_size = 4096 1886cf2a73cSMauro Carvalho Chehab 1896cf2a73cSMauro Carvalho Chehab:: 1906cf2a73cSMauro Carvalho Chehab 1916cf2a73cSMauro Carvalho Chehab [ root ] 1926cf2a73cSMauro Carvalho Chehab / . . . \ 1936cf2a73cSMauro Carvalho Chehab [entry_0] [entry_1] 1946cf2a73cSMauro Carvalho Chehab / . . . \ . . . \ 1956cf2a73cSMauro Carvalho Chehab [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] 1966cf2a73cSMauro Carvalho Chehab / ... \ / . . . \ / \ 1976cf2a73cSMauro Carvalho Chehab blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767 1986cf2a73cSMauro Carvalho Chehab 1996cf2a73cSMauro Carvalho Chehab 2006cf2a73cSMauro Carvalho ChehabOn-disk format 2016cf2a73cSMauro Carvalho Chehab============== 2026cf2a73cSMauro Carvalho Chehab 2036cf2a73cSMauro Carvalho ChehabThe verity kernel code does not read the verity metadata on-disk header. 2046cf2a73cSMauro Carvalho ChehabIt only reads the hash blocks which directly follow the header. 2056cf2a73cSMauro Carvalho ChehabIt is expected that a user-space tool will verify the integrity of the 2066cf2a73cSMauro Carvalho Chehabverity header. 2076cf2a73cSMauro Carvalho Chehab 2086cf2a73cSMauro Carvalho ChehabAlternatively, the header can be omitted and the dmsetup parameters can 2096cf2a73cSMauro Carvalho Chehabbe passed via the kernel command-line in a rooted chain of trust where 2106cf2a73cSMauro Carvalho Chehabthe command-line is verified. 2116cf2a73cSMauro Carvalho Chehab 2126cf2a73cSMauro Carvalho ChehabDirectly following the header (and with sector number padded to the next hash 2136cf2a73cSMauro Carvalho Chehabblock boundary) are the hash blocks which are stored a depth at a time 2146cf2a73cSMauro Carvalho Chehab(starting from the root), sorted in order of increasing index. 2156cf2a73cSMauro Carvalho Chehab 2166cf2a73cSMauro Carvalho ChehabThe full specification of kernel parameters and on-disk metadata format 2176cf2a73cSMauro Carvalho Chehabis available at the cryptsetup project's wiki page 2186cf2a73cSMauro Carvalho Chehab 2196cf2a73cSMauro Carvalho Chehab https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity 2206cf2a73cSMauro Carvalho Chehab 2216cf2a73cSMauro Carvalho ChehabStatus 2226cf2a73cSMauro Carvalho Chehab====== 2236cf2a73cSMauro Carvalho ChehabV (for Valid) is returned if every check performed so far was valid. 2246cf2a73cSMauro Carvalho ChehabIf any check failed, C (for Corruption) is returned. 2256cf2a73cSMauro Carvalho Chehab 2266cf2a73cSMauro Carvalho ChehabExample 2276cf2a73cSMauro Carvalho Chehab======= 2286cf2a73cSMauro Carvalho ChehabSet up a device:: 2296cf2a73cSMauro Carvalho Chehab 2306cf2a73cSMauro Carvalho Chehab # dmsetup create vroot --readonly --table \ 2316cf2a73cSMauro Carvalho Chehab "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ 2326cf2a73cSMauro Carvalho Chehab "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ 2336cf2a73cSMauro Carvalho Chehab "1234000000000000000000000000000000000000000000000000000000000000" 2346cf2a73cSMauro Carvalho Chehab 2356cf2a73cSMauro Carvalho ChehabA command line tool veritysetup is available to compute or verify 2366cf2a73cSMauro Carvalho Chehabthe hash tree or activate the kernel device. This is available from 2376cf2a73cSMauro Carvalho Chehabthe cryptsetup upstream repository https://gitlab.com/cryptsetup/cryptsetup/ 2386cf2a73cSMauro Carvalho Chehab(as a libcryptsetup extension). 2396cf2a73cSMauro Carvalho Chehab 2406cf2a73cSMauro Carvalho ChehabCreate hash on the device:: 2416cf2a73cSMauro Carvalho Chehab 2426cf2a73cSMauro Carvalho Chehab # veritysetup format /dev/sda1 /dev/sda2 2436cf2a73cSMauro Carvalho Chehab ... 2446cf2a73cSMauro Carvalho Chehab Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 2456cf2a73cSMauro Carvalho Chehab 2466cf2a73cSMauro Carvalho ChehabActivate the device:: 2476cf2a73cSMauro Carvalho Chehab 2486cf2a73cSMauro Carvalho Chehab # veritysetup create vroot /dev/sda1 /dev/sda2 \ 2496cf2a73cSMauro Carvalho Chehab 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 250