xref: /aosp_15_r20/system/security/fsverity/fsverity_manifest_generator.py (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1#!/usr/bin/env python3
2#
3# Copyright 2022 Google Inc. All rights reserved.
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`fsverity_manifest_generator` generates the a manifest file containing digests
19of target files.
20"""
21
22import argparse
23import os
24import subprocess
25import sys
26from fsverity_digests_pb2 import FSVerityDigests
27
28HASH_ALGORITHM = 'sha256'
29
30def _digest(fsverity_path, input_file):
31  cmd = [fsverity_path, 'digest', input_file]
32  cmd.extend(['--compact'])
33  cmd.extend(['--hash-alg', HASH_ALGORITHM])
34  out = subprocess.check_output(cmd, universal_newlines=True).strip()
35  return bytes(bytearray.fromhex(out))
36
37if __name__ == '__main__':
38  p = argparse.ArgumentParser(fromfile_prefix_chars='@')
39  p.add_argument(
40      '--output',
41      help='Path to the output manifest',
42      required=True)
43  p.add_argument(
44      '--fsverity-path',
45      help='path to the fsverity program',
46      required=True)
47  p.add_argument(
48      '--base-dir',
49      help='directory to use as a relative root for the inputs',
50      required=True)
51  p.add_argument(
52      'inputs',
53      nargs='*',
54      help='input file for the build manifest')
55  args = p.parse_args()
56
57  digests = FSVerityDigests()
58  for f in sorted(args.inputs):
59    # f is a full path for now; make it relative so it starts with {mount_point}/
60    digest = digests.digests[os.path.relpath(f, args.base_dir)]
61    digest.digest = _digest(args.fsverity_path, f)
62    digest.hash_alg = HASH_ALGORITHM
63
64  manifest = digests.SerializeToString()
65
66  with open(args.output, "wb") as f:
67    f.write(manifest)
68