Commit 97a20f12 authored by Bence Balogh's avatar Bence Balogh Committed by Dávid Vincze
Browse files

imgtool: Add public key's SHA256 hash calculation



Signed-off-by: default avatarDávid Házi <david.hazi@arm.com>
Signed-off-by: default avatarBence Balogh <bence.balogh@arm.com>
Change-Id: I91d5c07c1bb2b8abe2592cd49b2053c881465ba2
parent ed8d68af
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: Apache-2.0

import sys
from cryptography.hazmat.primitives.hashes import Hash, SHA256

AUTOGEN_MESSAGE = "/* Autogenerated by imgtool.py, do not edit. */"

@@ -34,11 +35,26 @@ class KeyClass(object):

    def emit_c_public(self, file=sys.stdout):
        self._emit(
                header="const unsigned char {}_pub_key[] = {{".format(self.shortname()),
                header="const unsigned char {}_pub_key[] = {{"
                       .format(self.shortname()),
                trailer="};",
                encoded_bytes=self.get_public_bytes(),
                indent="    ",
                len_format="const unsigned int {}_pub_key_len = {{}};".format(self.shortname()),
                len_format="const unsigned int {}_pub_key_len = {{}};"
                           .format(self.shortname()),
                file=file)

    def emit_c_public_hash(self, file=sys.stdout):
        digest = Hash(SHA256())
        digest.update(self.get_public_bytes())
        self._emit(
                header="const unsigned char {}_pub_key_hash[] = {{"
                       .format(self.shortname()),
                trailer="};",
                encoded_bytes=digest.finalize(),
                indent="    ",
                len_format="const unsigned int {}_pub_key_hash_len = {{}};"
                           .format(self.shortname()),
                file=file)

    def emit_raw_public(self, file=sys.stdout):
@@ -48,9 +64,19 @@ class KeyClass(object):
        else:
            sys.stdout.buffer.write(self.get_public_bytes())

    def emit_raw_public_hash(self, file=sys.stdout):
        digest = Hash(SHA256())
        digest.update(self.get_public_bytes())
        if file and file is not sys.stdout:
            with open(file, 'wb') as file:
                file.write(digest.finalize())
        else:
            sys.stdout.buffer.write(digest.finalize())

    def emit_rust_public(self, file=sys.stdout):
        self._emit(
                header="static {}_PUB_KEY: &[u8] = &[".format(self.shortname().upper()),
                header="static {}_PUB_KEY: &[u8] = &["
                       .format(self.shortname().upper()),
                trailer="];",
                encoded_bytes=self.get_public_bytes(),
                indent="    ",
+30 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ def gen_x25519(keyfile, passwd):


valid_langs = ['c', 'rust']
valid_hash_encodings = ['lang-c', 'raw']
valid_encodings = ['lang-c', 'lang-rust', 'pem', 'raw']
keygens = {
    'rsa-2048':   gen_rsa2048,
@@ -158,6 +159,34 @@ def getpub(key, encoding, lang, output):
        raise click.UsageError()


@click.option('-e', '--encoding', metavar='encoding',
              type=click.Choice(valid_hash_encodings),
              help='Valid encodings: {}. '
                   'Default value is {}.'
                   .format(', '.join(valid_hash_encodings),
                           valid_hash_encodings[0]))
@click.option('-k', '--key', metavar='filename', required=True)
@click.option('-o', '--output', metavar='output', required=False,
              help='Specify the output file\'s name. \
                    The stdout is used if it is not provided.')
@click.command(help='Dump the SHA256 hash of the public key')
def getpubhash(key, output, encoding):
    if not encoding:
        encoding = valid_hash_encodings[0]
    key = load_key(key)

    if not output:
        output = sys.stdout
    if key is None:
        print("Invalid passphrase")
    elif encoding == 'lang-c':
        key.emit_c_public_hash(file=output)
    elif encoding == 'raw':
        key.emit_raw_public_hash(file=output)
    else:
        raise click.UsageError()


@click.option('--minimal', default=False, is_flag=True,
              help='Reduce the size of the dumped private key to include only '
                   'the minimum amount of data required to decrypt. This '
@@ -486,6 +515,7 @@ def imgtool():

imgtool.add_command(keygen)
imgtool.add_command(getpub)
imgtool.add_command(getpubhash)
imgtool.add_command(getpriv)
imgtool.add_command(verify)
imgtool.add_command(sign)