binman: add sign option for binman
Introduce proof of concept for binman's new option which provides sign and replace FIT containers in binary images. Usage as example: from: mkimage -G privateky -r -o sha256,rsa4096 -F fit binman replace -i flash.bin -f fit.fit fit to: binman sign -i flash.bin -k privatekey -a sha256,rsa4096 -f fit.fit fit and to this one if it's need to be extracted, signed with key and put it back in image: binman sign -i flash.bin -k privatekey -a sha256,rsa4096 fit Signed-off-by: Ivan Mikhaylov <fr0st61te@gmail.com>
This commit is contained in:
parent
0f40e23fd2
commit
4023dc9c95
5 changed files with 62 additions and 1 deletions
|
@ -13,6 +13,7 @@
|
|||
#include <command.h>
|
||||
#include <console.h>
|
||||
#include <env.h>
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
#include <net.h>
|
||||
#include <version_string.h>
|
||||
|
|
|
@ -176,6 +176,19 @@ controlled by a description in the board device tree.'''
|
|||
replace_parser.add_argument('paths', type=str, nargs='*',
|
||||
help='Paths within file to replace (wildcard)')
|
||||
|
||||
sign_parser = subparsers.add_parser('sign',
|
||||
help='Sign entries in image')
|
||||
sign_parser.add_argument('-a', '--algo', type=str, required=True,
|
||||
help='Hash algorithm e.g. sha256,rsa4096')
|
||||
sign_parser.add_argument('-f', '--file', type=str, required=False,
|
||||
help='Input filename to sign')
|
||||
sign_parser.add_argument('-i', '--image', type=str, required=True,
|
||||
help='Image filename to update')
|
||||
sign_parser.add_argument('-k', '--key', type=str, required=True,
|
||||
help='Private key file for signing')
|
||||
sign_parser.add_argument('paths', type=str, nargs='*',
|
||||
help='Paths within file to sign (wildcard)')
|
||||
|
||||
if HAS_TESTS:
|
||||
test_parser = subparsers.add_parser('test', help='Run tests')
|
||||
test_parser.add_argument('-P', '--processes', type=int,
|
||||
|
|
|
@ -448,6 +448,29 @@ def ReplaceEntries(image_fname, input_fname, indir, entry_paths,
|
|||
AfterReplace(image, allow_resize=allow_resize, write_map=write_map)
|
||||
return image
|
||||
|
||||
def SignEntries(image_fname, input_fname, privatekey_fname, algo, entry_paths,
|
||||
write_map=False):
|
||||
"""Sign and replace the data from one or more entries from input files
|
||||
|
||||
Args:
|
||||
image_fname: Image filename to process
|
||||
input_fname: Single input filename to use if replacing one file, None
|
||||
otherwise
|
||||
algo: Hashing algorithm
|
||||
entry_paths: List of entry paths to sign
|
||||
privatekey_fname: Private key filename
|
||||
write_map (bool): True to write the map file
|
||||
"""
|
||||
image_fname = os.path.abspath(image_fname)
|
||||
image = Image.FromFile(image_fname)
|
||||
|
||||
BeforeReplace(image, allow_resize=True)
|
||||
|
||||
for entry_path in entry_paths:
|
||||
entry = image.FindEntryPath(entry_path)
|
||||
entry.UpdateSignatures(privatekey_fname, algo, input_fname)
|
||||
|
||||
AfterReplace(image, allow_resize=True, write_map=write_map)
|
||||
|
||||
def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
|
||||
"""Prepare the images to be processed and select the device tree
|
||||
|
@ -660,7 +683,7 @@ def Binman(args):
|
|||
tools.set_tool_paths(tool_paths or None)
|
||||
bintool.Bintool.set_tool_dir(args.tooldir)
|
||||
|
||||
if args.cmd in ['ls', 'extract', 'replace', 'tool']:
|
||||
if args.cmd in ['ls', 'extract', 'replace', 'tool', 'sign']:
|
||||
try:
|
||||
tout.init(args.verbosity)
|
||||
if args.cmd == 'replace':
|
||||
|
@ -679,6 +702,9 @@ def Binman(args):
|
|||
do_compress=not args.compressed,
|
||||
allow_resize=not args.fix_size, write_map=args.map)
|
||||
|
||||
if args.cmd == 'sign':
|
||||
SignEntries(args.image, args.file, args.key, args.algo, args.paths)
|
||||
|
||||
if args.cmd == 'tool':
|
||||
if args.list:
|
||||
bintool.Bintool.list_all()
|
||||
|
|
|
@ -835,3 +835,21 @@ class Entry_fit(Entry_section):
|
|||
|
||||
def CheckEntries(self):
|
||||
pass
|
||||
|
||||
def UpdateSignatures(self, privatekey_fname, algo, input_fname):
|
||||
uniq = self.GetUniqueName()
|
||||
args = [ '-G', privatekey_fname, '-r', '-o', algo, '-F' ]
|
||||
if input_fname:
|
||||
fname = input_fname
|
||||
else:
|
||||
fname = tools.get_output_filename('%s.fit' % uniq)
|
||||
tools.write_file(fname, self.GetData())
|
||||
args.append(fname)
|
||||
|
||||
if self.mkimage.run_cmd(*args) is None:
|
||||
# Bintool is missing; just use empty data as the output
|
||||
self.record_missing_bintool(self.mkimage)
|
||||
return
|
||||
|
||||
data = tools.read_file(fname)
|
||||
self.WriteData(data)
|
||||
|
|
|
@ -1014,3 +1014,6 @@ class Entry_section(Entry):
|
|||
for entry in entries.values():
|
||||
return entry.read_elf_segments()
|
||||
return None
|
||||
|
||||
def UpdateSignatures(self, privatekey_fname, algo, input_fname):
|
||||
self.Raise('Updating signatures is not supported with this entry type')
|
||||
|
|
Loading…
Reference in a new issue