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 | 20 | The salt is appended when hashing, digests are stored continuously and |
a739ff3f | 21 | the rest of the block is padded with zeroes. |
a4ffc152 MP |
22 | |
23 | 1 is the current format that should be used for new devices. | |
18068bdd | 24 | The salt is prepended when hashing and each digest is |
a739ff3f | 25 | padded with zeroes 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 | ||
0cc37c2d ST |
82 | ignore_zero_blocks |
83 | Do not verify blocks that are expected to contain zeroes and always return | |
84 | zeroes instead. This may be useful if the partition contains unused blocks | |
85 | that are not guaranteed to contain zeroes. | |
86 | ||
a739ff3f ST |
87 | use_fec_from_device <fec_dev> |
88 | Use forward error correction (FEC) to recover from corruption if hash | |
89 | verification fails. Use encoding data from the specified device. This | |
90 | may be the same device where data and hash blocks reside, in which case | |
91 | fec_start must be outside data and hash areas. | |
92 | ||
93 | If the encoding data covers additional metadata, it must be accessible | |
94 | on the hash device after the hash blocks. | |
95 | ||
96 | Note: block sizes for data and hash devices must match. Also, if the | |
97 | verity <dev> is encrypted the <fec_dev> should be too. | |
98 | ||
99 | fec_roots <num> | |
100 | Number of generator roots. This equals to the number of parity bytes in | |
101 | the encoding data. For example, in RS(M, N) encoding, the number of roots | |
102 | is M-N. | |
103 | ||
104 | fec_blocks <num> | |
105 | The number of encoding data blocks on the FEC device. The block size for | |
106 | the FEC device is <data_block_size>. | |
107 | ||
108 | fec_start <offset> | |
109 | This is the offset, in <data_block_size> blocks, from the start of the | |
110 | FEC device to the beginning of the encoding data. | |
111 | ||
112 | ||
a4ffc152 MP |
113 | Theory of operation |
114 | =================== | |
115 | ||
18068bdd | 116 | dm-verity is meant to be set up as part of a verified boot path. This |
a4ffc152 MP |
117 | may be anything ranging from a boot using tboot or trustedgrub to just |
118 | booting from a known-good device (like a USB drive or CD). | |
119 | ||
120 | When a dm-verity device is configured, it is expected that the caller | |
121 | has been authenticated in some way (cryptographic signatures, etc). | |
122 | After instantiation, all hashes will be verified on-demand during | |
123 | disk access. If they cannot be verified up to the root node of the | |
18068bdd | 124 | tree, the root hash, then the I/O will fail. This should detect |
a4ffc152 MP |
125 | tampering with any data on the device and the hash data. |
126 | ||
127 | Cryptographic hashes are used to assert the integrity of the device on a | |
18068bdd MB |
128 | per-block basis. This allows for a lightweight hash computation on first read |
129 | into the page cache. Block hashes are stored linearly, aligned to the nearest | |
130 | block size. | |
a4ffc152 | 131 | |
a739ff3f ST |
132 | If forward error correction (FEC) support is enabled any recovery of |
133 | corrupted data will be verified using the cryptographic hash of the | |
134 | corresponding data. This is why combining error correction with | |
135 | integrity checking is essential. | |
136 | ||
a4ffc152 MP |
137 | Hash Tree |
138 | --------- | |
139 | ||
140 | Each node in the tree is a cryptographic hash. If it is a leaf node, the hash | |
18068bdd MB |
141 | of some data block on disk is calculated. If it is an intermediary node, |
142 | the hash of a number of child nodes is calculated. | |
a4ffc152 MP |
143 | |
144 | Each entry in the tree is a collection of neighboring nodes that fit in one | |
145 | block. The number is determined based on block_size and the size of the | |
146 | selected cryptographic digest algorithm. The hashes are linearly-ordered in | |
147 | this entry and any unaligned trailing space is ignored but included when | |
148 | calculating the parent node. | |
149 | ||
150 | The tree looks something like: | |
151 | ||
152 | alg = sha256, num_blocks = 32768, block_size = 4096 | |
153 | ||
154 | [ root ] | |
155 | / . . . \ | |
156 | [entry_0] [entry_1] | |
157 | / . . . \ . . . \ | |
158 | [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] | |
159 | / ... \ / . . . \ / \ | |
160 | blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767 | |
161 | ||
162 | ||
163 | On-disk format | |
164 | ============== | |
165 | ||
18068bdd MB |
166 | The verity kernel code does not read the verity metadata on-disk header. |
167 | It only reads the hash blocks which directly follow the header. | |
168 | It is expected that a user-space tool will verify the integrity of the | |
169 | verity header. | |
a4ffc152 | 170 | |
18068bdd MB |
171 | Alternatively, the header can be omitted and the dmsetup parameters can |
172 | be passed via the kernel command-line in a rooted chain of trust where | |
173 | the command-line is verified. | |
a4ffc152 MP |
174 | |
175 | Directly following the header (and with sector number padded to the next hash | |
176 | block boundary) are the hash blocks which are stored a depth at a time | |
177 | (starting from the root), sorted in order of increasing index. | |
178 | ||
18068bdd MB |
179 | The full specification of kernel parameters and on-disk metadata format |
180 | is available at the cryptsetup project's wiki page | |
e44f23b3 | 181 | https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity |
18068bdd | 182 | |
a4ffc152 MP |
183 | Status |
184 | ====== | |
185 | V (for Valid) is returned if every check performed so far was valid. | |
186 | If any check failed, C (for Corruption) is returned. | |
187 | ||
188 | Example | |
189 | ======= | |
18068bdd MB |
190 | Set up a device: |
191 | # dmsetup create vroot --readonly --table \ | |
192 | "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ | |
a4ffc152 MP |
193 | "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ |
194 | "1234000000000000000000000000000000000000000000000000000000000000" | |
195 | ||
196 | A command line tool veritysetup is available to compute or verify | |
18068bdd | 197 | the hash tree or activate the kernel device. This is available from |
e44f23b3 | 198 | the cryptsetup upstream repository https://gitlab.com/cryptsetup/cryptsetup/ |
18068bdd MB |
199 | (as a libcryptsetup extension). |
200 | ||
201 | Create hash on the device: | |
202 | # veritysetup format /dev/sda1 /dev/sda2 | |
203 | ... | |
204 | Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 | |
205 | ||
206 | Activate the device: | |
207 | # veritysetup create vroot /dev/sda1 /dev/sda2 \ | |
208 | 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 |