+ log_err(cd, _("Verity device detected corruption after activation."));
+
+ r = 0;
+out:
+ dm_targets_free(cd, &dmd);
+ return r;
+}
+
+int VERITY_dump(struct crypt_device *cd,
+ struct crypt_params_verity *verity_hdr,
+ const char *root_hash,
+ unsigned int root_hash_size,
+ struct device *fec_device)
+{
+ uint64_t hash_blocks, verity_blocks, fec_blocks = 0, rs_blocks = 0;
+ bool fec_on_hash_device = false;
+
+ hash_blocks = VERITY_hash_blocks(cd, verity_hdr);
+ verity_blocks = VERITY_hash_offset_block(verity_hdr) + hash_blocks;
+
+ if (fec_device && verity_hdr->fec_roots) {
+ fec_blocks = VERITY_FEC_blocks(cd, fec_device, verity_hdr);
+ rs_blocks = VERITY_FEC_RS_blocks(fec_blocks, verity_hdr->fec_roots);
+ fec_on_hash_device = device_is_identical(crypt_metadata_device(cd), fec_device) > 0;
+ /*
+ * No way to access fec_area_offset directly.
+ * Assume FEC area starts directly after hash blocks.
+ */
+ if (fec_on_hash_device)
+ verity_blocks += rs_blocks;
+ }
+
+ log_std(cd, "VERITY header information for %s\n", device_path(crypt_metadata_device(cd)));
+ log_std(cd, "UUID: \t%s\n", crypt_get_uuid(cd) ?: "");
+ log_std(cd, "Hash type: \t%u\n", verity_hdr->hash_type);
+ log_std(cd, "Data blocks: \t%" PRIu64 "\n", verity_hdr->data_size);
+ log_std(cd, "Data block size: \t%u\n", verity_hdr->data_block_size);
+ log_std(cd, "Hash blocks: \t%" PRIu64 "\n", hash_blocks);
+ log_std(cd, "Hash block size: \t%u\n", verity_hdr->hash_block_size);
+ log_std(cd, "Hash algorithm: \t%s\n", verity_hdr->hash_name);
+ if (fec_device && fec_blocks) {
+ log_std(cd, "FEC RS roots: \t%" PRIu32 "\n", verity_hdr->fec_roots);
+ log_std(cd, "FEC blocks: \t%" PRIu64 "\n", rs_blocks);
+ }
+
+ log_std(cd, "Salt: \t");
+ if (verity_hdr->salt_size)
+ crypt_log_hex(cd, verity_hdr->salt, verity_hdr->salt_size, "", 0, NULL);
+ else
+ log_std(cd, "-");
+ log_std(cd, "\n");
+
+ if (root_hash) {
+ log_std(cd, "Root hash: \t");
+ crypt_log_hex(cd, root_hash, root_hash_size, "", 0, NULL);
+ log_std(cd, "\n");
+ }
+
+ /* As dump can take only hash device, we have no idea about offsets here. */
+ if (verity_hdr->hash_area_offset == 0)
+ log_std(cd, "Hash device size: \t%" PRIu64 " [bytes]\n", verity_blocks * verity_hdr->hash_block_size);
+
+ if (fec_device && verity_hdr->fec_area_offset == 0 && fec_blocks && !fec_on_hash_device)
+ log_std(cd, "FEC device size: \t%" PRIu64 " [bytes]\n", rs_blocks * verity_hdr->data_block_size);
+