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