diff options
author | Jiyong Park <jiyong@google.com> | 2018-08-28 22:06:56 +0900 |
---|---|---|
committer | Jiyong Park <jiyong@google.com> | 2018-08-29 00:55:18 +0900 |
commit | d372d3bec77576fe73018d37e0f57796a5a37843 (patch) | |
tree | 4b2f38c31585dfcc6d5e84528ea2a4629941ea55 /apexer/apexer.py | |
parent | 34c0fbbfcde17170222914642e5222ad993e0d3e (diff) |
The file system image is protected by dm-verity
The file system image in an APEX is now protected by dm-verity. The hash
tree and vbmeta descriptors, etc are appened to the file system using
the tool avbtool.
Testing-purpose public/private key pairs are also added to sign the
metadata.
Bug: 112458021
Test: ./runtests.sh
Change-Id: If32b99adaf2267e9b84a761c50fa3c7bc4854e2a
Diffstat (limited to 'apexer/apexer.py')
-rw-r--r-- | apexer/apexer.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/apexer/apexer.py b/apexer/apexer.py index fd57c36..bb148c1 100644 --- a/apexer/apexer.py +++ b/apexer/apexer.py @@ -25,6 +25,7 @@ Typical usage: apexer input_dir output.apex import argparse import json import os +import re import shutil import subprocess import sys @@ -43,6 +44,8 @@ def ParseArgs(argv): help='selinux file contexts file') parser.add_argument('--canned_fs_config', required=True, help='canned_fs_config specifies uid/gid/mode of files') + parser.add_argument('--key', required=True, + help='path to the private key file') parser.add_argument('input_dir', metavar='INPUT_DIR', help='the directory having files to be packaged') parser.add_argument('output', metavar='OUTPUT', @@ -74,6 +77,10 @@ def GetDirSize(dir_name): size += os.path.getsize(os.path.join(dirpath, f)) return size +def RoundUp(size, unit): + assert unit & (unit - 1) == 0 + return (size + unit - 1) & (~(unit - 1)) + def PrepareAndroidManifest(packagename): template = """\ @@ -190,6 +197,37 @@ def CreateApex(args, work_dir): cmd.append(img_file) RunCommand(cmd, args.verbose) + # partition size should be bigger than file system size + size of the hash + # tree + size of the vbmeta and the footer. + # However, since we don't know the size of the last three before running + # avbtool, use an arbitrary big (+100MB) here. + # TODO(b/113320014) eliminate this heuristic + partition_size = os.stat(img_file).st_size + (100 * 1024 * 1024) + cmd = ['avbtool'] + cmd.append('add_hashtree_footer') + cmd.append('--do_not_generate_fec') + cmd.extend(['--partition_size', str(partition_size)]) + cmd.extend(['--partition_name', 'image']) + cmd.extend(['--algorithm', 'SHA256_RSA4096']) + cmd.extend(['--key', args.key]) + cmd.extend(['--image', img_file]) + RunCommand(cmd, args.verbose) + + # Get the minimum size of the partition required. + # TODO(b/113320014) eliminate this step + info, _ = RunCommand(['avbtool', 'info_image', '--image', img_file], args.verbose) + vbmeta_offset = int(re.search('VBMeta\ offset:\ *([0-9]+)', info).group(1)) + vbmeta_size = int(re.search('VBMeta\ size:\ *([0-9]+)', info).group(1)) + partition_size = RoundUp(vbmeta_offset + vbmeta_size, 4096) + 4096 + + # Resize to the minimum size + # TODO(b/113320014) eliminate this step + cmd = ['avbtool'] + cmd.append('resize_image') + cmd.extend(['--image', img_file]) + cmd.extend(['--partition_size', str(partition_size)]) + RunCommand(cmd, args.verbose) + # package the image file and APEX manifest as an APK. # The AndroidManifest file is automatically generated. android_manifest_file = os.path.join(work_dir, 'AndroidManifest.xml') |