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