|  | 
|  | 1 | +#!/usr/bin/env python3 | 
|  | 2 | +# Copyright lowRISC contributors (OpenTitan project). | 
|  | 3 | +# Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | 4 | +# SPDX-License-Identifier: Apache-2.0 | 
|  | 5 | +"""Generates cryptolib_build_info.c for cryptolib build.""" | 
|  | 6 | + | 
|  | 7 | +import argparse | 
|  | 8 | +import logging as log | 
|  | 9 | +from pathlib import Path | 
|  | 10 | + | 
|  | 11 | +import version_file | 
|  | 12 | + | 
|  | 13 | + | 
|  | 14 | +def generate_build_info_c_source(scm_revision: int) -> str: | 
|  | 15 | +    """Return the contents of a C source file that defines `kCryptoLibBuildInfo`. | 
|  | 16 | +
 | 
|  | 17 | +    Args: | 
|  | 18 | +        scm_revision: SHA1 sum identifying the current SCM revision. | 
|  | 19 | +    """ | 
|  | 20 | +    SHA1_BYTE_CNT = 20 | 
|  | 21 | +    assert 0 < scm_revision < 2**(SHA1_BYTE_CNT * 8) | 
|  | 22 | +    scm_rev_byte_be = scm_revision.to_bytes(SHA1_BYTE_CNT, "big") | 
|  | 23 | +    scm_revision_high = int.from_bytes(scm_rev_byte_be[0:4], "big") | 
|  | 24 | +    scm_revision_low = int.from_bytes(scm_rev_byte_be[4:8], "big") | 
|  | 25 | + | 
|  | 26 | +    return f""" | 
|  | 27 | +// Copyright lowRISC contributors (OpenTitan project). | 
|  | 28 | +// Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | 29 | +// SPDX-License-Identifier: Apache-2.0 | 
|  | 30 | +// | 
|  | 31 | +// --------- W A R N I N G: A U T O - G E N E R A T E D   C O D E !! ---------// | 
|  | 32 | +
 | 
|  | 33 | +#include "sw/device/lib/crypto/drivers/cryptolib_build_info.h" | 
|  | 34 | +
 | 
|  | 35 | +#include "sw/device/lib/crypto/include/datatypes.h" | 
|  | 36 | +
 | 
|  | 37 | +OT_USED | 
|  | 38 | +const cryptolib_build_info_t kCryptoLibBuildInfo = {{ | 
|  | 39 | +  .scm_revision = (cryptolib_build_info_scm_revision_t){{ | 
|  | 40 | +    .scm_revision_low = {scm_revision_low:#010x}, | 
|  | 41 | +    .scm_revision_high = {scm_revision_high:#010x}, | 
|  | 42 | +  }}, | 
|  | 43 | +  .version = (uint32_t)kCryptoLibVersion, | 
|  | 44 | +  .released = (bool)kCryptoLibReleased, | 
|  | 45 | +}}; | 
|  | 46 | +""" | 
|  | 47 | + | 
|  | 48 | + | 
|  | 49 | +def read_version_file(version_info_path, default_version) -> int: | 
|  | 50 | +    """ | 
|  | 51 | +    Search for the scm revision variable and interprets | 
|  | 52 | +    the contents as a big-endian hex literal. Return an error | 
|  | 53 | +    if the revision cannot be found. | 
|  | 54 | +    """ | 
|  | 55 | + | 
|  | 56 | +    version_info = version_file.VersionInformation(version_info_path) | 
|  | 57 | +    version = version_info.cryptolib_scm_revision(default_version) | 
|  | 58 | +    return int(version, base=16) | 
|  | 59 | + | 
|  | 60 | + | 
|  | 61 | +def write_source_file(outdir: Path, contents: str) -> Path: | 
|  | 62 | +    """Creates cryptolib_build_info.c in `outdir`. Returns the path to the new file.""" | 
|  | 63 | + | 
|  | 64 | +    source_out_path = outdir / "cryptolib_build_info.c" | 
|  | 65 | + | 
|  | 66 | +    outdir.mkdir(parents=True, exist_ok=True) | 
|  | 67 | +    with source_out_path.open(mode='w', encoding='utf-8') as fout: | 
|  | 68 | +        fout.write(contents) | 
|  | 69 | + | 
|  | 70 | +    return source_out_path | 
|  | 71 | + | 
|  | 72 | + | 
|  | 73 | +def main(): | 
|  | 74 | +    log.basicConfig(format="%(levelname)s: %(message)s") | 
|  | 75 | + | 
|  | 76 | +    parser = argparse.ArgumentParser(prog="cryptolib_build_info") | 
|  | 77 | +    parser.add_argument('--outdir', | 
|  | 78 | +                        '-o', | 
|  | 79 | +                        required=True, | 
|  | 80 | +                        type=Path, | 
|  | 81 | +                        help='Output Directory') | 
|  | 82 | +    parser.add_argument('--ot_version_file', | 
|  | 83 | +                        type=Path, | 
|  | 84 | +                        help='Path to a file with the OpenTitan Version') | 
|  | 85 | +    parser.add_argument('--default_version', | 
|  | 86 | +                        type=str, | 
|  | 87 | +                        help='Version to use if the version file does not indicate a version') | 
|  | 88 | + | 
|  | 89 | +    args = parser.parse_args() | 
|  | 90 | + | 
|  | 91 | +    # Extract version stamp from file | 
|  | 92 | +    version = read_version_file(args.ot_version_file, args.default_version) | 
|  | 93 | +    log.info("Version: %x" % (version, )) | 
|  | 94 | + | 
|  | 95 | +    generated_source = generate_build_info_c_source(version) | 
|  | 96 | +    out_path = write_source_file(args.outdir, generated_source) | 
|  | 97 | +    log.info("Generated new source file: %s" % (out_path)) | 
|  | 98 | + | 
|  | 99 | + | 
|  | 100 | +if __name__ == "__main__": | 
|  | 101 | +    main() | 
0 commit comments