2 * dm-verity volume handling
4 * Copyright (C) 2012, Red Hat, Inc. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 static unsigned get_bits_up(unsigned u)
37 static unsigned get_bits_down(unsigned u)
45 static int verify_zero(struct crypt_device *cd, FILE *wr, unsigned bytes)
50 if (fread(block, bytes, 1, wr) != 1)
52 for (i = 0; i < bytes; i++)
54 log_err(cd, "spare area is not zeroed at position %lld\n",
55 (long long)ftello(wr) - bytes);
61 static int verify_hash_block(const char *hash_name, int version,
62 char *hash, size_t hash_size,
63 const char *data, size_t data_size,
64 const char *salt, size_t salt_size)
66 struct crypt_hash *ctx = NULL;
69 if (crypt_hash_init(&ctx, hash_name))
72 if (version == 1 && (r = crypt_hash_write(ctx, salt, salt_size)))
75 if ((r = crypt_hash_write(ctx, data, data_size)))
78 if (version == 0 && (r = crypt_hash_write(ctx, salt, salt_size)))
81 r = crypt_hash_final(ctx, hash, hash_size);
83 crypt_hash_destroy(ctx);
87 static int create_or_verify(struct crypt_device *cd, FILE *rd, FILE *wr,
88 off_t data_block, int data_block_size,
89 off_t hash_block, int hash_block_size,
90 off_t blocks, int version,
91 const char *hash_name, int verify,
92 char *calculated_digest, unsigned digest_size,
93 const char *salt, unsigned salt_size)
95 char left_block[hash_block_size];
96 char data_buffer[data_block_size];
97 char read_digest[digest_size];
98 off_t hash_per_block = 1 << get_bits_down(hash_block_size / digest_size);
99 off_t blocks_to_write = (blocks + hash_per_block - 1) / hash_per_block;
100 unsigned i, left_bytes;
101 off_t digest_size_full = 1 << get_bits_up(digest_size);
103 unsigned long long pos_rd = (unsigned long long)data_block * data_block_size;
104 unsigned long long pos_wr = (unsigned long long)hash_block * hash_block_size;
106 if (fseeko(rd, pos_rd, SEEK_SET))
109 if (wr && fseeko(wr, pos_wr, SEEK_SET))
112 memset(left_block, 0, hash_block_size);
113 while (blocks_to_write--) {
114 left_bytes = hash_block_size;
115 for (i = 0; i < hash_per_block; i++) {
119 if (fread(data_buffer, data_block_size, 1, rd) != 1)
122 if (verify_hash_block(hash_name, version,
123 calculated_digest, digest_size,
124 data_buffer, data_block_size,
131 if (fread(read_digest, digest_size, 1, wr) != 1)
133 if (memcmp(read_digest, calculated_digest, digest_size)) {
134 log_err(cd, "verification failed at position %lld\n",
135 (long long)ftello(rd) - data_block_size);
139 if (fwrite(calculated_digest, digest_size, 1, wr) != 1)
143 left_bytes -= digest_size;
145 if (digest_size_full - digest_size) {
147 r = verify_zero(cd, wr, digest_size_full - digest_size);
150 } else if (fwrite(left_block, digest_size_full - digest_size, 1, wr) != 1)
153 left_bytes -= digest_size_full;
156 if (wr && left_bytes) {
158 r = verify_zero(cd , wr, left_bytes);
161 } else if (fwrite(left_block, left_bytes, 1, wr) != 1)
169 static int VERITY_create_or_verify_hash(struct crypt_device *cd,
172 const char *hash_name,
173 const char *hash_device,
174 const char *data_device,
178 long long hash_position,
180 unsigned digest_size,
184 static FILE *data_file = NULL;
185 static FILE *hash_file = NULL, *hash_file_2;
188 char calculated_digest[digest_size];
189 off_t hash_level_block[VERITY_MAX_LEVELS];
190 off_t hash_level_size[VERITY_MAX_LEVELS];
191 off_t data_file_blocks;
192 uint64_t data_device_size;
193 unsigned long long hash_per_block, hash_per_block_bits;
196 log_dbg("Userspace hash %s %s, data device %s, data blocks %u, hash device %s, offset %u.",
197 verify ? "verification" : "creation", hash_name, data_device,
198 (unsigned)data_blocks, hash_device, (unsigned)hash_position);
201 r = device_size(data_device, &data_device_size);
205 data_file_blocks = data_device_size / data_block_size;
207 data_file_blocks = data_blocks;
209 hash_per_block_bits = get_bits_down(hash_block_size / digest_size);
210 hash_per_block = 1 << hash_per_block_bits;
211 if (!hash_per_block_bits) {
212 log_err(cd, "at least two hashes must fit in a hash file block\n");
217 if (data_file_blocks) {
218 while (hash_per_block_bits * levels < 64 &&
219 (unsigned long long)(data_file_blocks - 1) >>
220 (hash_per_block_bits * levels))
224 if (levels > VERITY_MAX_LEVELS) {
225 log_err(cd, "too many tree levels\n");
229 for (i = levels - 1; i >= 0; i--) {
231 hash_level_block[i] = hash_position;
232 // verity position of block data_file_blocks at level i
233 s = data_file_blocks >> (i * hash_per_block_bits);
234 s = (s + hash_per_block - 1) / hash_per_block;
235 hash_level_size[i] = s;
236 if (hash_position + s < hash_position ||
237 (off_t)(hash_position + s) < 0 ||
238 (off_t)(hash_position + s) != hash_position + s) {
239 log_err(cd, "hash device offset overflow\n");
245 data_file = fopen(data_device, "r");
247 log_err(cd, "Cannot open %s.\n", data_device);
252 hash_file = fopen(hash_device, verify ? "r" : "r+");
254 log_err(cd, "Cannot open %s.\n", hash_device);
259 memset(calculated_digest, 0, digest_size);
261 for (i = 0; i < levels; i++) {
263 r = create_or_verify(cd, data_file, hash_file,
265 hash_level_block[i], hash_block_size,
266 data_file_blocks, version, hash_name, verify,
267 calculated_digest, digest_size, salt, salt_size);
271 hash_file_2 = fopen(hash_device, "r");
276 r = create_or_verify(cd, hash_file_2, hash_file,
277 hash_level_block[i - 1], hash_block_size,
278 hash_level_block[i], hash_block_size,
279 hash_level_size[i - 1], version, hash_name, verify,
280 calculated_digest, digest_size, salt, salt_size);
288 r = create_or_verify(cd, hash_file, NULL,
289 hash_level_block[levels - 1], hash_block_size,
291 1, version, hash_name, verify,
292 calculated_digest, digest_size, salt, salt_size);
294 r = create_or_verify(cd, data_file, NULL,
297 data_file_blocks, version, hash_name, verify,
298 calculated_digest, digest_size, salt, salt_size);
301 log_err(cd, "Hash of data area verification failed.\n");
304 log_dbg("Hash of data area successfully verified.");
306 /* root hash verification */
308 r = memcmp(root_hash, calculated_digest, digest_size) ? -EPERM : 0;
310 log_err(cd, "Root hash verification failed.\n");
312 log_dbg("Root hash successfully verified.");
314 fsync(fileno(hash_file));
315 memcpy(root_hash, calculated_digest, digest_size);
325 /* Verify verity device using userspace crypto backend */
326 int VERITY_verify(struct crypt_device *cd,
327 struct crypt_params_verity *verity_hdr,
328 const char *data_device,
329 const char *hash_device,
330 const char *root_hash,
331 size_t root_hash_size)
333 int r = VERITY_create_or_verify_hash(cd, 1,
335 verity_hdr->hash_name,
338 verity_hdr->hash_block_size,
339 verity_hdr->data_block_size,
340 verity_hdr->data_size,
341 VERITY_hash_offset_block(verity_hdr),
342 CONST_CAST(char*)root_hash,
345 verity_hdr->salt_size);
348 log_err(cd, "Userspace hash verification failed.\n");
353 int VERITY_create(struct crypt_device *cd,
354 struct crypt_params_verity *verity_hdr,
355 const char *data_device,
356 const char *hash_device,
358 size_t root_hash_size)
360 if (verity_hdr->salt_size > VERITY_MAX_SALT_SIZE)
363 return VERITY_create_or_verify_hash(cd, 0,
365 verity_hdr->hash_name,
368 verity_hdr->hash_block_size,
369 verity_hdr->data_block_size,
370 verity_hdr->data_size,
371 VERITY_hash_offset_block(verity_hdr),
375 verity_hdr->salt_size);