1#!/usr/bin/env python3
2#
3# Copyright 2021, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18"""Generate a Generic Boot Image certificate suitable for VTS verification."""
19
20from argparse import ArgumentParser
21import shlex
22import subprocess
23
24
25def generate_gki_certificate(image, avbtool, name, algorithm, key, salt,
26                             additional_avb_args, output):
27    """Shell out to avbtool to generate a GKI certificate."""
28
29    # Need to specify a value of --partition_size for avbtool to work.
30    # We use 64 MB below, but avbtool will not resize the boot image to
31    # this size because --do_not_append_vbmeta_image is also specified.
32    avbtool_cmd = [
33        avbtool, 'add_hash_footer',
34        '--partition_name', name,
35        '--partition_size', str(64 * 1024 * 1024),
36        '--image', image,
37        '--algorithm', algorithm,
38        '--key', key,
39        '--do_not_append_vbmeta_image',
40        '--output_vbmeta_image', output,
41    ]
42
43    if salt is not None:
44        avbtool_cmd += ['--salt', salt]
45
46    avbtool_cmd += additional_avb_args
47
48    subprocess.check_call(avbtool_cmd)
49
50
51def parse_cmdline():
52    parser = ArgumentParser(add_help=True)
53
54    # Required args.
55    parser.add_argument('image', help='path to the image')
56    parser.add_argument('-o', '--output', required=True,
57                        help='output certificate file name')
58    parser.add_argument('--name', required=True,
59                        choices=['boot', 'generic_kernel'],
60                        help='name of the image to be certified')
61    parser.add_argument('--algorithm', required=True,
62                        help='AVB signing algorithm')
63    parser.add_argument('--key', required=True,
64                        help='path to the RSA private key')
65
66    # Optional args.
67    parser.add_argument('--avbtool', default='avbtool',
68                        help='path to the avbtool executable')
69    parser.add_argument('--salt', help='salt to use when computing image hash')
70    parser.add_argument('--additional_avb_args', default=[], action='append',
71                        help='additional arguments to be forwarded to avbtool')
72
73    args = parser.parse_args()
74
75    additional_avb_args = []
76    for a in args.additional_avb_args:
77        additional_avb_args.extend(shlex.split(a))
78    args.additional_avb_args = additional_avb_args
79
80    return args
81
82
83def main():
84    args = parse_cmdline()
85    generate_gki_certificate(
86        image=args.image, avbtool=args.avbtool, name=args.name,
87        algorithm=args.algorithm, key=args.key, salt=args.salt,
88        additional_avb_args=args.additional_avb_args,
89        output=args.output,
90    )
91
92
93if __name__ == '__main__':
94    main()
95