#!/usr/bin/env perl # Generate dm-verity hashes and sign the root hash # # Output looks like # # VERITY header information for hdd.img # UUID: 73532888-a3e9-4f16-a50a-1d03a265b94f # Hash type: 1 # Data blocks: 7680 # Data block size: 4096 # Hash block size: 4096 # Hash algorithm: sha256 # Salt: 3d0cd593d29715005794c4e1cd5164c14ba6456c3dbd2c6d8a26007c01ca9937 # Root hash: 91beda90d7fa1ab92463344966eb56ec9706f4f26063933a86d701a02a961a10 # my $usage = <<""; Usage: size=32 dd if=/dev/zero of=hdd.img bs=1M count=$size mkfs.ext4 -b 4096 ./hdd.img mkdir /tmp/loop sudo mount -o loop hdd.img /tmp/loop (populate /tmp/loop) sudo umount /tmp/loop veritysetup \ --hash-offset $[$size*1024*1024] \ --data-blocks $[$size*1024*1024/4096] \ format hdd.img hdd.img \ | ./verity-sign /dev/sda1 \ | gpg --clearsign \ | tee hdd.table use warnings; use strict; my $dev = shift; local $_ = ; chomp; my ($orig_device) = /^VERITY header information for (.*)/ or die "Missing VERITY header\n"; my %params; $dev ||= $orig_device; while(<>) { chomp; my ($key,$value) = split /:\s+/; $params{$key} = $value; } my @missing; # All the necessary parameters were in the header, generate # the command to mount the filesystem my $data_blocks = $params{'Data blocks'} or push @missing, 'Data blocks'; my $data_block_size = $params{'Data block size'} or push @missing, 'Data block size'; my $hash_block_size = $params{'Hash block size'} or push @missing, 'Hash block size'; my $salt = $params{'Salt'} or push @missing, 'Salt'; my $root_hash = $params{'Root hash'} or push @missing, 'Root hash'; my $hash_type = $params{'Hash type'} or push @missing, 'Hash type'; my $hash_algorithm = $params{'Hash algorithm'} or push @missing, 'Hash algorithm'; # Check for any missing parameters die "Missing parameter: ", join(', ', @missing), "\n" if @missing; # Compute the derived parameters my $data_size = $data_blocks * $data_block_size; my $data_size_512b = $data_size / 512; my $first_hash_block = $data_blocks + 1; # The table must be on a single line my $table = sprintf "0 %d verity %d %s %s %d %d %d %d %s %s %s", $data_size_512b, $hash_type, $dev, $dev, $data_block_size, $hash_block_size, $data_blocks, $first_hash_block, $hash_algorithm, $root_hash, $salt, ; print "dmsetup create --readonly boot --table '$table'\n"; print "dmsetup mknodes boot\n"; print "mount -o ro /dev/mapper/boot /boot\n"; __END__