Commit | Line | Data |
---|---|---|
a4ffc152 MP |
1 | dm-verity |
2 | ========== | |
3 | ||
4 | Device-Mapper's "verity" target provides transparent integrity checking of | |
5 | block devices using a cryptographic digest provided by the kernel crypto API. | |
6 | This target is read-only. | |
7 | ||
8 | Construction Parameters | |
9 | ======================= | |
18068bdd | 10 | <version> <dev> <hash_dev> |
a4ffc152 MP |
11 | <data_block_size> <hash_block_size> |
12 | <num_data_blocks> <hash_start_block> | |
13 | <algorithm> <digest> <salt> | |
65ff5b7d | 14 | [<#opt_params> <opt_params>] |
a4ffc152 MP |
15 | |
16 | <version> | |
18068bdd | 17 | This is the type of the on-disk hash format. |
a4ffc152 MP |
18 | |
19 | 0 is the original format used in the Chromium OS. | |
18068bdd MB |
20 | The salt is appended when hashing, digests are stored continuously and |
21 | the rest of the block is padded with zeros. | |
a4ffc152 MP |
22 | |
23 | 1 is the current format that should be used for new devices. | |
18068bdd MB |
24 | The salt is prepended when hashing and each digest is |
25 | padded with zeros to the power of two. | |
a4ffc152 MP |
26 | |
27 | <dev> | |
18068bdd | 28 | This is the device containing data, the integrity of which needs to be |
a4ffc152 MP |
29 | checked. It may be specified as a path, like /dev/sdaX, or a device number, |
30 | <major>:<minor>. | |
31 | ||
32 | <hash_dev> | |
18068bdd | 33 | This is the device that supplies the hash tree data. It may be |
a4ffc152 | 34 | specified similarly to the device path and may be the same device. If the |
18068bdd MB |
35 | same device is used, the hash_start should be outside the configured |
36 | dm-verity device. | |
a4ffc152 MP |
37 | |
38 | <data_block_size> | |
18068bdd MB |
39 | The block size on a data device in bytes. |
40 | Each block corresponds to one digest on the hash device. | |
a4ffc152 MP |
41 | |
42 | <hash_block_size> | |
18068bdd | 43 | The size of a hash block in bytes. |
a4ffc152 MP |
44 | |
45 | <num_data_blocks> | |
46 | The number of data blocks on the data device. Additional blocks are | |
47 | inaccessible. You can place hashes to the same partition as data, in this | |
48 | case hashes are placed after <num_data_blocks>. | |
49 | ||
50 | <hash_start_block> | |
51 | This is the offset, in <hash_block_size>-blocks, from the start of hash_dev | |
52 | to the root block of the hash tree. | |
53 | ||
54 | <algorithm> | |
55 | The cryptographic hash algorithm used for this device. This should | |
56 | be the name of the algorithm, like "sha1". | |
57 | ||
58 | <digest> | |
59 | The hexadecimal encoding of the cryptographic hash of the root hash block | |
60 | and the salt. This hash should be trusted as there is no other authenticity | |
61 | beyond this point. | |
62 | ||
63 | <salt> | |
64 | The hexadecimal encoding of the salt value. | |
65 | ||
65ff5b7d ST |
66 | <#opt_params> |
67 | Number of optional parameters. If there are no optional parameters, | |
68 | the optional paramaters section can be skipped or #opt_params can be zero. | |
69 | Otherwise #opt_params is the number of following arguments. | |
70 | ||
71 | Example of optional parameters section: | |
72 | 1 ignore_corruption | |
73 | ||
74 | ignore_corruption | |
75 | Log corrupted blocks, but allow read operations to proceed normally. | |
76 | ||
77 | restart_on_corruption | |
78 | Restart the system when a corrupted block is discovered. This option is | |
79 | not compatible with ignore_corruption and requires user space support to | |
80 | avoid restart loops. | |
81 | ||
a4ffc152 MP |
82 | Theory of operation |
83 | =================== | |
84 | ||
18068bdd | 85 | dm-verity is meant to be set up as part of a verified boot path. This |
a4ffc152 MP |
86 | may be anything ranging from a boot using tboot or trustedgrub to just |
87 | booting from a known-good device (like a USB drive or CD). | |
88 | ||
89 | When a dm-verity device is configured, it is expected that the caller | |
90 | has been authenticated in some way (cryptographic signatures, etc). | |
91 | After instantiation, all hashes will be verified on-demand during | |
92 | disk access. If they cannot be verified up to the root node of the | |
18068bdd | 93 | tree, the root hash, then the I/O will fail. This should detect |
a4ffc152 MP |
94 | tampering with any data on the device and the hash data. |
95 | ||
96 | Cryptographic hashes are used to assert the integrity of the device on a | |
18068bdd MB |
97 | per-block basis. This allows for a lightweight hash computation on first read |
98 | into the page cache. Block hashes are stored linearly, aligned to the nearest | |
99 | block size. | |
a4ffc152 MP |
100 | |
101 | Hash Tree | |
102 | --------- | |
103 | ||
104 | Each node in the tree is a cryptographic hash. If it is a leaf node, the hash | |
18068bdd MB |
105 | of some data block on disk is calculated. If it is an intermediary node, |
106 | the hash of a number of child nodes is calculated. | |
a4ffc152 MP |
107 | |
108 | Each entry in the tree is a collection of neighboring nodes that fit in one | |
109 | block. The number is determined based on block_size and the size of the | |
110 | selected cryptographic digest algorithm. The hashes are linearly-ordered in | |
111 | this entry and any unaligned trailing space is ignored but included when | |
112 | calculating the parent node. | |
113 | ||
114 | The tree looks something like: | |
115 | ||
116 | alg = sha256, num_blocks = 32768, block_size = 4096 | |
117 | ||
118 | [ root ] | |
119 | / . . . \ | |
120 | [entry_0] [entry_1] | |
121 | / . . . \ . . . \ | |
122 | [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] | |
123 | / ... \ / . . . \ / \ | |
124 | blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767 | |
125 | ||
126 | ||
127 | On-disk format | |
128 | ============== | |
129 | ||
18068bdd MB |
130 | The verity kernel code does not read the verity metadata on-disk header. |
131 | It only reads the hash blocks which directly follow the header. | |
132 | It is expected that a user-space tool will verify the integrity of the | |
133 | verity header. | |
a4ffc152 | 134 | |
18068bdd MB |
135 | Alternatively, the header can be omitted and the dmsetup parameters can |
136 | be passed via the kernel command-line in a rooted chain of trust where | |
137 | the command-line is verified. | |
a4ffc152 MP |
138 | |
139 | Directly following the header (and with sector number padded to the next hash | |
140 | block boundary) are the hash blocks which are stored a depth at a time | |
141 | (starting from the root), sorted in order of increasing index. | |
142 | ||
18068bdd MB |
143 | The full specification of kernel parameters and on-disk metadata format |
144 | is available at the cryptsetup project's wiki page | |
e44f23b3 | 145 | https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity |
18068bdd | 146 | |
a4ffc152 MP |
147 | Status |
148 | ====== | |
149 | V (for Valid) is returned if every check performed so far was valid. | |
150 | If any check failed, C (for Corruption) is returned. | |
151 | ||
152 | Example | |
153 | ======= | |
18068bdd MB |
154 | Set up a device: |
155 | # dmsetup create vroot --readonly --table \ | |
156 | "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ | |
a4ffc152 MP |
157 | "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ |
158 | "1234000000000000000000000000000000000000000000000000000000000000" | |
159 | ||
160 | A command line tool veritysetup is available to compute or verify | |
18068bdd | 161 | the hash tree or activate the kernel device. This is available from |
e44f23b3 | 162 | the cryptsetup upstream repository https://gitlab.com/cryptsetup/cryptsetup/ |
18068bdd MB |
163 | (as a libcryptsetup extension). |
164 | ||
165 | Create hash on the device: | |
166 | # veritysetup format /dev/sda1 /dev/sda2 | |
167 | ... | |
168 | Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 | |
169 | ||
170 | Activate the device: | |
171 | # veritysetup create vroot /dev/sda1 /dev/sda2 \ | |
172 | 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 |