linuxboot/verity-sign
Trammell Hudson 8e4e37360f
mount /boot
2016-08-07 13:49:30 -04:00

105 lines
2.4 KiB
Perl
Executable File

#!/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 \
| gpg --clearsign \
| 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;
# 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__