1#! /usr/bin/env python3 2# 3# ----------------------------------------------------------------------------- 4# Copyright (c) 2020-2024, Arm Limited. All rights reserved. 5# 6# SPDX-License-Identifier: BSD-3-Clause 7# 8# ----------------------------------------------------------------------------- 9 10import os 11import sys 12import click 13from jinja2 import Environment, FileSystemLoader 14from cryptography.hazmat.primitives.hashes import Hash, SHA256 15 16# Add the cwd to the path so that if there is a version of imgtool in there then 17# it gets used over the system imgtool. Used so that imgtool from upstream 18# mcuboot is preferred over system imgtool 19cwd = os.getcwd() 20sys.path = [cwd] + sys.path 21import imgtool 22import imgtool.main 23 24parser_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../')) 25sys.path.append(parser_path) 26 27# This works around Python 2 and Python 3 handling character encodings 28# differently. More information about this issue at 29# https://click.palletsprojects.com/en/5.x/python3 30os.environ['LC_ALL'] = 'C.UTF-8' 31os.environ['LANG'] = 'C.UTF-8' 32 33 34def get_key_hash_c_array(key_file): 35 key = imgtool.main.load_key(key_file) 36 digest = Hash(SHA256()) 37 digest.update(key.get_public_bytes()) 38 return hex_to_c_array(digest.finalize()) 39 40 41@click.argument('outfile') 42@click.option('--bl2_rot_priv_key_0', metavar='filename', required=True) 43@click.option('--bl2_rot_priv_key_1', metavar='filename', required=False) 44@click.option('--bl2_rot_priv_key_2', metavar='filename', required=False) 45@click.option('--bl2_rot_priv_key_3', metavar='filename', required=False) 46@click.option('--template_path', metavar='filename', required=True) 47@click.option('--secure_debug_pk', metavar='key', required=False) 48@click.option('--huk', metavar='key', required=False) 49@click.option('--iak', metavar='key', required=False) 50@click.option('--boot_seed', metavar='seed', required=False) 51@click.option('--implementation_id', metavar='id', required=False) 52@click.option('--certification_reference', metavar='reference', default="", 53 required=False) 54@click.option('--verification_service_url', metavar='url', default="", 55 required=False) 56@click.option('--entropy_seed', metavar='seed', required=False) 57@click.command(help='''Creates a .c file with the given keys, using the\n 58 provisioning_data_template.jinja2 template which is located in 59 "template_path" and outputs it to "outfile"''') 60def generate_provisioning_data_c(outfile, bl2_rot_priv_key_0, 61 bl2_rot_priv_key_1, 62 template_path, bl2_rot_priv_key_2, 63 bl2_rot_priv_key_3, 64 secure_debug_pk, huk, iak, boot_seed, 65 implementation_id, 66 certification_reference, 67 verification_service_url, 68 entropy_seed): 69 70 environment = Environment(loader=FileSystemLoader(template_path)) 71 template = environment.get_template("provisioning_data_template.jinja2") 72 73 bl2_rot_pub_key_0_hash = "" 74 if bool(bl2_rot_priv_key_0) is True: 75 bl2_rot_pub_key_0_hash = get_key_hash_c_array(bl2_rot_priv_key_0) 76 77 bl2_rot_pub_key_1_hash = "" 78 if bool(bl2_rot_priv_key_1) is True: 79 bl2_rot_pub_key_1_hash = get_key_hash_c_array(bl2_rot_priv_key_1) 80 81 bl2_rot_pub_key_2_hash = "" 82 if bool(bl2_rot_priv_key_2) is True: 83 bl2_rot_pub_key_2_hash = get_key_hash_c_array(bl2_rot_priv_key_2) 84 85 bl2_rot_pub_key_3_hash = "" 86 if bool(bl2_rot_priv_key_3) is True: 87 bl2_rot_pub_key_3_hash = get_key_hash_c_array(bl2_rot_priv_key_3) 88 89 if bool(huk) is False: 90 huk = hex_to_c_array(os.urandom(32)) 91 92 if bool(iak) is False: 93 iak = hex_to_c_array(os.urandom(32)) 94 95 if bool(boot_seed) is False: 96 boot_seed = hex_to_c_array(os.urandom(32)) 97 98 if bool(implementation_id) is False: 99 implementation_id = hex_to_c_array(os.urandom(32)) 100 101 if bool(entropy_seed) is False: 102 entropy_seed = hex_to_c_array(os.urandom(64)) 103 104 key_arrays = { 105 "bl2_rotpk_0": bl2_rot_pub_key_0_hash, 106 "bl2_rotpk_1": bl2_rot_pub_key_1_hash, 107 "bl2_rotpk_2": bl2_rot_pub_key_2_hash, 108 "bl2_rotpk_3": bl2_rot_pub_key_3_hash, 109 "secure_debug_pk": secure_debug_pk, 110 "huk": huk, 111 "iak": iak, 112 "iak_len": "32", 113 "boot_seed": boot_seed, 114 "implementation_id": implementation_id, 115 "certification_reference": certification_reference, 116 "verification_service_url": verification_service_url, 117 "entropy_seed": entropy_seed 118 } 119 120 with open(outfile, "w") as F: 121 F.write(template.render(key_arrays)) 122 123 124def hex_to_c_array(hex_val): 125 c_array = "" 126 for count, b in enumerate(hex_val): 127 if count % 8 == 0 and count != 0: 128 c_array = c_array + '\n' 129 c_array = c_array + "0x{:02x}, ".format(b) 130 131 return c_array 132 133 134if __name__ == '__main__': 135 generate_provisioning_data_c() 136