2016-08-06 03:17:41 +00:00
|
|
|
#!/usr/bin/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 \
|
2016-08-07 17:49:30 +00:00
|
|
|
| gpg --clearsign \
|
2016-08-06 03:17:41 +00:00
|
|
|
| tee hdd.table
|
|
|
|
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
my $dev = shift;
|
|
|
|
|
|
|
|
local $_ = <STDIN>;
|
|
|
|
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;
|
|
|
|
|
2016-08-06 03:28:20 +00:00
|
|
|
# Compute the derived parameters
|
2016-08-06 03:17:41 +00:00
|
|
|
my $data_size = $data_blocks * $data_block_size;
|
|
|
|
my $data_size_512b = $data_size / 512;
|
|
|
|
my $first_hash_block = $data_blocks + 1;
|
|
|
|
|
2016-08-06 03:28:20 +00:00
|
|
|
# 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";
|
2016-08-07 17:49:30 +00:00
|
|
|
print "mount -o ro /dev/mapper/boot /boot\n";
|
2016-08-06 03:17:41 +00:00
|
|
|
|
|
|
|
__END__
|