1bbaeed4dSRouven Czerwinski#!/usr/bin/env python3 21bb92983SJerome Forissier# SPDX-License-Identifier: BSD-2-Clause 3bc420748SJens Wiklander# 4bc420748SJens Wiklander# Copyright (c) 2015, Linaro Limited 5bc420748SJens Wiklander 6049aefa8SJerome Forissier 7bc420748SJens Wiklanderdef get_args(): 8bc420748SJens Wiklander import argparse 9bc420748SJens Wiklander 10bc420748SJens Wiklander parser = argparse.ArgumentParser() 11049aefa8SJerome Forissier parser.add_argument( 121718b6c9SMarkus S. Wamser '--prefix', required=True, 13bc420748SJens Wiklander help='Prefix for the public key exponent and modulus in c file') 141718b6c9SMarkus S. Wamser parser.add_argument( 151718b6c9SMarkus S. Wamser '--out', required=True, 16bc420748SJens Wiklander help='Name of c file for the public key') 17bc420748SJens Wiklander parser.add_argument('--key', required=True, help='Name of key file') 18bc420748SJens Wiklander 19bc420748SJens Wiklander return parser.parse_args() 20bc420748SJens Wiklander 21049aefa8SJerome Forissier 22bc420748SJens Wiklanderdef main(): 23bc420748SJens Wiklander import array 24*169eac19SDonald Chan from cryptography.hazmat.backends import default_backend 25*169eac19SDonald Chan from cryptography.hazmat.primitives import serialization 26*169eac19SDonald Chan from cryptography.hazmat.primitives.asymmetric import rsa 27bc420748SJens Wiklander 28049aefa8SJerome Forissier args = get_args() 29bc420748SJens Wiklander 30*169eac19SDonald Chan with open(args.key, 'rb') as f: 31*169eac19SDonald Chan data = f.read() 32*169eac19SDonald Chan 33*169eac19SDonald Chan try: 34*169eac19SDonald Chan key = serialization.load_pem_private_key(data, password=None, 35*169eac19SDonald Chan backend=default_backend()) 36*169eac19SDonald Chan key = key.public_key() 37*169eac19SDonald Chan except ValueError: 38*169eac19SDonald Chan key = serialization.load_pem_public_key(data, 39*169eac19SDonald Chan backend=default_backend()) 40bc420748SJens Wiklander 410a6f2bcaSMarkus S. Wamser # Refuse public exponent with more than 32 bits. Otherwise the C 420a6f2bcaSMarkus S. Wamser # compiler may simply truncate the value and proceed. 430a6f2bcaSMarkus S. Wamser # This will lead to TAs seemingly having invalid signatures with a 440a6f2bcaSMarkus S. Wamser # possible security issue for any e = k*2^32 + 1 (for any integer k). 45*169eac19SDonald Chan if key.public_numbers().e > 0xffffffff: 460a6f2bcaSMarkus S. Wamser raise ValueError( 470a6f2bcaSMarkus S. Wamser 'Unsupported large public exponent detected. ' + 480a6f2bcaSMarkus S. Wamser 'OP-TEE handles only public exponents up to 2^32 - 1.') 490a6f2bcaSMarkus S. Wamser 501718b6c9SMarkus S. Wamser with open(args.out, 'w') as f: 51049aefa8SJerome Forissier f.write("#include <stdint.h>\n") 52049aefa8SJerome Forissier f.write("#include <stddef.h>\n\n") 53bc420748SJens Wiklander f.write("const uint32_t " + args.prefix + "_exponent = " + 54*169eac19SDonald Chan str(key.public_numbers().e) + ";\n\n") 55bc420748SJens Wiklander f.write("const uint8_t " + args.prefix + "_modulus[] = {\n") 56049aefa8SJerome Forissier i = 0 57*169eac19SDonald Chan nbuf = key.public_numbers().n.to_bytes(key.key_size >> 3, 'big') 58*169eac19SDonald Chan for x in array.array("B", nbuf): 59bc420748SJens Wiklander f.write("0x" + '{0:02x}'.format(x) + ",") 60049aefa8SJerome Forissier i = i + 1 61bc420748SJens Wiklander if i % 8 == 0: 62049aefa8SJerome Forissier f.write("\n") 63bc420748SJens Wiklander else: 64049aefa8SJerome Forissier f.write(" ") 65049aefa8SJerome Forissier f.write("};\n") 66049aefa8SJerome Forissier f.write("const size_t " + args.prefix + "_modulus_size = sizeof(" + 67bc420748SJens Wiklander args.prefix + "_modulus);\n") 68bc420748SJens Wiklander 69049aefa8SJerome Forissier 70bc420748SJens Wiklanderif __name__ == "__main__": 71bc420748SJens Wiklander main() 72