]>
Commit | Line | Data |
---|---|---|
75c89069 JK |
1 | #!/usr/bin/env python3 |
2 | # SPDX-License-Identifier: GPL-2.0-only | |
3 | # | |
4 | # Public key to dtsi converter. | |
5 | # | |
6 | # Copyright (c) Siemens AG, 2022 | |
7 | # | |
8 | ||
9 | from argparse import ArgumentParser, FileType | |
10 | from os.path import basename, splitext | |
11 | from Cryptodome.PublicKey import RSA | |
12 | from Cryptodome.Util.number import inverse | |
13 | ||
14 | def int_to_bytestr(n, length=None): | |
15 | if not length: | |
16 | length = (n.bit_length() + 7) // 8 | |
17 | byte_array = n.to_bytes(length, 'big') | |
18 | return ' '.join(['{:02x}'.format(byte) for byte in byte_array]) | |
19 | ||
20 | ap = ArgumentParser(description='Public key to dtsi converter') | |
21 | ||
22 | ap.add_argument('--hash', '-H', default='sha256', | |
23 | help='hash to be used with key (default: sha256)') | |
24 | ap.add_argument('--required-conf', '-c', action='store_true', | |
25 | help='mark key required for configuration') | |
26 | ap.add_argument('--required-image', '-i', action='store_true', | |
27 | help='mark key required for image') | |
28 | ap.add_argument('--spl', '-s', action='store_true', | |
29 | help='mark key for usage in SPL') | |
30 | ap.add_argument('key_file', metavar='KEY_FILE', type=FileType('r'), | |
31 | help='key file (formats: X.509, PKCS#1, OpenSSH)') | |
32 | ap.add_argument('dtsi_file', metavar='DTSI_FILE', type=FileType('w'), | |
33 | help='dtsi output file') | |
34 | ||
35 | args = ap.parse_args() | |
36 | ||
37 | key_name, _ = splitext(basename(args.key_file.name)) | |
38 | ||
39 | key_data = args.key_file.read() | |
40 | key = RSA.importKey(key_data) | |
41 | ||
42 | r_squared = (2**key.size_in_bits())**2 % key.n | |
43 | n0_inverse = 2**32 - inverse(key.n, 2**32) | |
44 | ||
45 | out = args.dtsi_file | |
46 | out.write('/ {\n') | |
47 | out.write('\tsignature {\n') | |
48 | out.write('\t\tkey-{} {{\n'.format(key_name)) | |
49 | out.write('\t\t\tkey-name-hint = "{}";\n'.format(key_name)) | |
50 | out.write('\t\t\talgo = "{},rsa{}";\n'.format(args.hash, key.size_in_bits())) | |
51 | out.write('\t\t\trsa,num-bits = <{}>;\n'.format(key.size_in_bits())) | |
52 | out.write('\t\t\trsa,modulus = [{}];\n'.format(int_to_bytestr(key.n))) | |
53 | out.write('\t\t\trsa,exponent = [{}];\n'.format(int_to_bytestr(key.e, 8))) | |
54 | out.write('\t\t\trsa,r-squared = [{}];\n'.format(int_to_bytestr(r_squared))) | |
55 | out.write('\t\t\trsa,n0-inverse = <0x{:x}>;\n'.format(n0_inverse)) | |
56 | if args.required_conf: | |
57 | out.write('\t\t\trequired = "conf";\n') | |
58 | elif args.required_image: | |
59 | out.write('\t\t\trequired = "image";\n') | |
60 | if args.spl: | |
61 | out.write('\t\t\tu-boot,dm-spl;\n') | |
62 | out.write('\t\t};\n') | |
63 | out.write('\t};\n') | |
64 | out.write('};\n') |