mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
binman: ti-secure: Add support for TI signing
The ti-secure entry contains certificate for binaries that will be loaded or booted by system firmware whereas the ti-secure-rom entry contains certificate for binaries that will be booted by ROM. Support for both these types of certificates is necessary for booting of K3 devices. Reviewed-by: Simon Glass <sjg@chromium.org> [vigneshr@ti.com: fixed inconsist cert generation by multiple packing] Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
This commit is contained in:
parent
6c66ccf26c
commit
78144826bb
13 changed files with 924 additions and 8 deletions
51
board/ti/keys/custMpk.pem
Normal file
51
board/ti/keys/custMpk.pem
Normal file
|
@ -0,0 +1,51 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
10
board/ti/keys/ti-degenerate-key.pem
Normal file
10
board/ti/keys/ti-degenerate-key.pem
Normal file
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBWwIBAAKBgQDRfrnXQaP0k6vRK/gZ+bDflSU6y1JagGeQ/b+QYuiDz14japog
|
||||
8fRSu5WBsAxaSaySAUwS3L9Ppw+hGMecmyIJ494aMfZTtk1g49gU58joduiRnu7e
|
||||
QSZHMnehhuNlfD7A2tAAKnxIYuabs8zHYM/SS9Ne7t3kIQMbKfUSzNy6qQIBAQIB
|
||||
AQJBAOelUA376o6w3HkShXfN+shaOZYqFuTJ9exLMwsLp7DZKXB5F9I4JJ+Vkvho
|
||||
k6QWs7vkhleLSYUZknXHYm26ZE0CQQDnhTtd4PTBoZPjPXOeYMJFtEdMNy0XP6ey
|
||||
bcce389ugoY7BEkvASrd8PHgJQHziepgWOG4DGp33c64Hfq4zI3NAgEBAgEBAkA0
|
||||
RbK4uqoLciQluesTPU6lBy7Se3Dw0F9xBqlF5SR4KI6q+zQrHpBKyFOofMHZgizR
|
||||
iCrL55cxEM146zMw3AnF
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -15,6 +15,13 @@ import hashlib
|
|||
from binman import bintool
|
||||
from u_boot_pylib import tools
|
||||
|
||||
|
||||
VALID_SHAS = [256, 384, 512, 224]
|
||||
SHA_OIDS = {256:'2.16.840.1.101.3.4.2.1',
|
||||
384:'2.16.840.1.101.3.4.2.2',
|
||||
512:'2.16.840.1.101.3.4.2.3',
|
||||
224:'2.16.840.1.101.3.4.2.4'}
|
||||
|
||||
class Bintoolopenssl(bintool.Bintool):
|
||||
"""openssl tool
|
||||
|
||||
|
@ -74,6 +81,243 @@ imageSize = INTEGER:{len(indata)}
|
|||
'-sha512']
|
||||
return self.run_cmd(*args)
|
||||
|
||||
def x509_cert_sysfw(self, cert_fname, input_fname, key_fname, sw_rev,
|
||||
config_fname, req_dist_name_dict):
|
||||
"""Create a certificate to be booted by system firmware
|
||||
|
||||
Args:
|
||||
cert_fname (str): Filename of certificate to create
|
||||
input_fname (str): Filename containing data to sign
|
||||
key_fname (str): Filename of .pem file
|
||||
sw_rev (int): Software revision
|
||||
config_fname (str): Filename to write fconfig into
|
||||
req_dist_name_dict (dict): Dictionary containing key-value pairs of
|
||||
req_distinguished_name section extensions, must contain extensions for
|
||||
C, ST, L, O, OU, CN and emailAddress
|
||||
|
||||
Returns:
|
||||
str: Tool output
|
||||
"""
|
||||
indata = tools.read_file(input_fname)
|
||||
hashval = hashlib.sha512(indata).hexdigest()
|
||||
with open(config_fname, 'w', encoding='utf-8') as outf:
|
||||
print(f'''[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = v3_ca
|
||||
prompt = no
|
||||
dirstring_type = nobmp
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = {req_dist_name_dict['C']}
|
||||
ST = {req_dist_name_dict['ST']}
|
||||
L = {req_dist_name_dict['L']}
|
||||
O = {req_dist_name_dict['O']}
|
||||
OU = {req_dist_name_dict['OU']}
|
||||
CN = {req_dist_name_dict['CN']}
|
||||
emailAddress = {req_dist_name_dict['emailAddress']}
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:true
|
||||
1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
|
||||
1.3.6.1.4.1.294.1.34 = ASN1:SEQUENCE:sysfw_image_integrity
|
||||
1.3.6.1.4.1.294.1.35 = ASN1:SEQUENCE:sysfw_image_load
|
||||
|
||||
[ swrv ]
|
||||
swrv = INTEGER:{sw_rev}
|
||||
|
||||
[ sysfw_image_integrity ]
|
||||
shaType = OID:2.16.840.1.101.3.4.2.3
|
||||
shaValue = FORMAT:HEX,OCT:{hashval}
|
||||
imageSize = INTEGER:{len(indata)}
|
||||
|
||||
[ sysfw_image_load ]
|
||||
destAddr = FORMAT:HEX,OCT:00000000
|
||||
authInPlace = INTEGER:2
|
||||
''', file=outf)
|
||||
args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
|
||||
'-outform', 'DER', '-out', cert_fname, '-config', config_fname,
|
||||
'-sha512']
|
||||
return self.run_cmd(*args)
|
||||
|
||||
def x509_cert_rom(self, cert_fname, input_fname, key_fname, sw_rev,
|
||||
config_fname, req_dist_name_dict, cert_type, bootcore,
|
||||
bootcore_opts, load_addr, sha):
|
||||
"""Create a certificate
|
||||
|
||||
Args:
|
||||
cert_fname (str): Filename of certificate to create
|
||||
input_fname (str): Filename containing data to sign
|
||||
key_fname (str): Filename of .pem file
|
||||
sw_rev (int): Software revision
|
||||
config_fname (str): Filename to write fconfig into
|
||||
req_dist_name_dict (dict): Dictionary containing key-value pairs of
|
||||
req_distinguished_name section extensions, must contain extensions for
|
||||
C, ST, L, O, OU, CN and emailAddress
|
||||
cert_type (int): Certification type
|
||||
bootcore (int): Booting core
|
||||
load_addr (int): Load address of image
|
||||
sha (int): Hash function
|
||||
|
||||
Returns:
|
||||
str: Tool output
|
||||
"""
|
||||
indata = tools.read_file(input_fname)
|
||||
hashval = hashlib.sha512(indata).hexdigest()
|
||||
with open(config_fname, 'w', encoding='utf-8') as outf:
|
||||
print(f'''
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = v3_ca
|
||||
prompt = no
|
||||
dirstring_type = nobmp
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = {req_dist_name_dict['C']}
|
||||
ST = {req_dist_name_dict['ST']}
|
||||
L = {req_dist_name_dict['L']}
|
||||
O = {req_dist_name_dict['O']}
|
||||
OU = {req_dist_name_dict['OU']}
|
||||
CN = {req_dist_name_dict['CN']}
|
||||
emailAddress = {req_dist_name_dict['emailAddress']}
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:true
|
||||
1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq
|
||||
1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity
|
||||
1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
|
||||
# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption
|
||||
1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug
|
||||
|
||||
[ boot_seq ]
|
||||
certType = INTEGER:{cert_type}
|
||||
bootCore = INTEGER:{bootcore}
|
||||
bootCoreOpts = INTEGER:{bootcore_opts}
|
||||
destAddr = FORMAT:HEX,OCT:{load_addr:08x}
|
||||
imageSize = INTEGER:{len(indata)}
|
||||
|
||||
[ image_integrity ]
|
||||
shaType = OID:{SHA_OIDS[sha]}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval}
|
||||
|
||||
[ swrv ]
|
||||
swrv = INTEGER:{sw_rev}
|
||||
|
||||
# [ encryption ]
|
||||
# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV
|
||||
# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS
|
||||
# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
|
||||
# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
|
||||
|
||||
[ debug ]
|
||||
debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
|
||||
debugType = INTEGER:4
|
||||
coreDbgEn = INTEGER:0
|
||||
coreDbgSecEn = INTEGER:0
|
||||
''', file=outf)
|
||||
args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
|
||||
'-outform', 'DER', '-out', cert_fname, '-config', config_fname,
|
||||
'-sha512']
|
||||
return self.run_cmd(*args)
|
||||
|
||||
def x509_cert_rom_combined(self, cert_fname, input_fname, key_fname, sw_rev,
|
||||
config_fname, req_dist_name_dict, load_addr, sha, total_size, num_comps,
|
||||
sysfw_inner_cert_ext_boot_sequence_string, dm_data_ext_boot_sequence_string,
|
||||
imagesize_sbl, hashval_sbl, load_addr_sysfw, imagesize_sysfw,
|
||||
hashval_sysfw, load_addr_sysfw_data, imagesize_sysfw_data,
|
||||
hashval_sysfw_data, sysfw_inner_cert_ext_boot_block,
|
||||
dm_data_ext_boot_block):
|
||||
"""Create a certificate
|
||||
|
||||
Args:
|
||||
cert_fname (str): Filename of certificate to create
|
||||
input_fname (str): Filename containing data to sign
|
||||
key_fname (str): Filename of .pem file
|
||||
sw_rev (int): Software revision
|
||||
config_fname (str): Filename to write fconfig into
|
||||
req_dist_name_dict (dict): Dictionary containing key-value pairs of
|
||||
req_distinguished_name section extensions, must contain extensions for
|
||||
C, ST, L, O, OU, CN and emailAddress
|
||||
cert_type (int): Certification type
|
||||
bootcore (int): Booting core
|
||||
load_addr (int): Load address of image
|
||||
sha (int): Hash function
|
||||
|
||||
Returns:
|
||||
str: Tool output
|
||||
"""
|
||||
indata = tools.read_file(input_fname)
|
||||
hashval = hashlib.sha512(indata).hexdigest()
|
||||
sha_type = SHA_OIDS[sha]
|
||||
with open(config_fname, 'w', encoding='utf-8') as outf:
|
||||
print(f'''
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = v3_ca
|
||||
prompt = no
|
||||
dirstring_type = nobmp
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C = {req_dist_name_dict['C']}
|
||||
ST = {req_dist_name_dict['ST']}
|
||||
L = {req_dist_name_dict['L']}
|
||||
O = {req_dist_name_dict['O']}
|
||||
OU = {req_dist_name_dict['OU']}
|
||||
CN = {req_dist_name_dict['CN']}
|
||||
emailAddress = {req_dist_name_dict['emailAddress']}
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:true
|
||||
1.3.6.1.4.1.294.1.3=ASN1:SEQUENCE:swrv
|
||||
1.3.6.1.4.1.294.1.9=ASN1:SEQUENCE:ext_boot_info
|
||||
|
||||
[swrv]
|
||||
swrv=INTEGER:{sw_rev}
|
||||
|
||||
[ext_boot_info]
|
||||
extImgSize=INTEGER:{total_size}
|
||||
numComp=INTEGER:{num_comps}
|
||||
sbl=SEQUENCE:sbl
|
||||
sysfw=SEQUENCE:sysfw
|
||||
sysfw_data=SEQUENCE:sysfw_data
|
||||
{sysfw_inner_cert_ext_boot_sequence_string}
|
||||
{dm_data_ext_boot_sequence_string}
|
||||
|
||||
[sbl]
|
||||
compType = INTEGER:1
|
||||
bootCore = INTEGER:16
|
||||
compOpts = INTEGER:0
|
||||
destAddr = FORMAT:HEX,OCT:{load_addr:08x}
|
||||
compSize = INTEGER:{imagesize_sbl}
|
||||
shaType = OID:{sha_type}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval_sbl}
|
||||
|
||||
[sysfw]
|
||||
compType = INTEGER:2
|
||||
bootCore = INTEGER:0
|
||||
compOpts = INTEGER:0
|
||||
destAddr = FORMAT:HEX,OCT:{load_addr_sysfw:08x}
|
||||
compSize = INTEGER:{imagesize_sysfw}
|
||||
shaType = OID:{sha_type}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval_sysfw}
|
||||
|
||||
[sysfw_data]
|
||||
compType = INTEGER:18
|
||||
bootCore = INTEGER:0
|
||||
compOpts = INTEGER:0
|
||||
destAddr = FORMAT:HEX,OCT:{load_addr_sysfw_data:08x}
|
||||
compSize = INTEGER:{imagesize_sysfw_data}
|
||||
shaType = OID:{sha_type}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval_sysfw_data}
|
||||
|
||||
{sysfw_inner_cert_ext_boot_block}
|
||||
|
||||
{dm_data_ext_boot_block}
|
||||
''', file=outf)
|
||||
args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
|
||||
'-outform', 'DER', '-out', cert_fname, '-config', config_fname,
|
||||
'-sha512']
|
||||
return self.run_cmd(*args)
|
||||
|
||||
def fetch(self, method):
|
||||
"""Fetch handler for openssl
|
||||
|
||||
|
|
|
@ -1712,6 +1712,71 @@ the included board config binaries. Example::
|
|||
|
||||
|
||||
|
||||
.. _etype_ti_secure:
|
||||
|
||||
Entry: ti-secure: Entry containing a TI x509 certificate binary
|
||||
---------------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- content: List of phandles to entries to sign
|
||||
- keyfile: Filename of file containing key to sign binary with
|
||||
- sha: Hash function to be used for signing
|
||||
|
||||
Output files:
|
||||
- input.<unique_name> - input file passed to openssl
|
||||
- config.<unique_name> - input file generated for openssl (which is
|
||||
used as the config file)
|
||||
- cert.<unique_name> - output file generated by openssl (which is
|
||||
used as the entry contents)
|
||||
|
||||
openssl signs the provided data, using the TI templated config file and
|
||||
writes the signature in this entry. This allows verification that the
|
||||
data is genuine.
|
||||
|
||||
|
||||
|
||||
.. _etype_ti_secure_rom:
|
||||
|
||||
Entry: ti-secure-rom: Entry containing a TI x509 certificate binary for images booted by ROM
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- keyfile: Filename of file containing key to sign binary with
|
||||
- combined: boolean if device follows combined boot flow
|
||||
- countersign: boolean if device contains countersigned system firmware
|
||||
- load: load address of SPL
|
||||
- sw-rev: software revision
|
||||
- sha: Hash function to be used for signing
|
||||
- core: core on which bootloader runs, valid cores are 'secure' and 'public'
|
||||
- content: phandle of SPL in case of legacy bootflow or phandles of component binaries
|
||||
in case of combined bootflow
|
||||
|
||||
The following properties are only for generating a combined bootflow binary:
|
||||
- sysfw-inner-cert: boolean if binary contains sysfw inner certificate
|
||||
- dm-data: boolean if binary contains dm-data binary
|
||||
- content-sbl: phandle of SPL binary
|
||||
- content-sysfw: phandle of sysfw binary
|
||||
- content-sysfw-data: phandle of sysfw-data or tifs-data binary
|
||||
- content-sysfw-inner-cert (optional): phandle of sysfw inner certificate binary
|
||||
- content-dm-data (optional): phandle of dm-data binary
|
||||
- load-sysfw: load address of sysfw binary
|
||||
- load-sysfw-data: load address of sysfw-data or tifs-data binary
|
||||
- load-sysfw-inner-cert (optional): load address of sysfw inner certificate binary
|
||||
- load-dm-data (optional): load address of dm-data binary
|
||||
|
||||
Output files:
|
||||
- input.<unique_name> - input file passed to openssl
|
||||
- config.<unique_name> - input file generated for openssl (which is
|
||||
used as the config file)
|
||||
- cert.<unique_name> - output file generated by openssl (which is
|
||||
used as the entry contents)
|
||||
|
||||
openssl signs the provided data, using the TI templated config file and
|
||||
writes the signature in this entry. This allows verification that the
|
||||
data is genuine.
|
||||
|
||||
|
||||
|
||||
.. _etype_u_boot:
|
||||
|
||||
Entry: u-boot: U-Boot flat binary
|
||||
|
|
78
tools/binman/etype/ti_secure.py
Normal file
78
tools/binman/etype/ti_secure.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
|
||||
# Written by Neha Malcom Francis <n-francis@ti.com>
|
||||
#
|
||||
|
||||
# Support for generation of TI secured binary blobs
|
||||
|
||||
from binman.entry import EntryArg
|
||||
from binman.etype.x509_cert import Entry_x509_cert
|
||||
|
||||
from dtoc import fdt_util
|
||||
|
||||
class Entry_ti_secure(Entry_x509_cert):
|
||||
"""Entry containing a TI x509 certificate binary
|
||||
|
||||
Properties / Entry arguments:
|
||||
- content: List of phandles to entries to sign
|
||||
- keyfile: Filename of file containing key to sign binary with
|
||||
- sha: Hash function to be used for signing
|
||||
|
||||
Output files:
|
||||
- input.<unique_name> - input file passed to openssl
|
||||
- config.<unique_name> - input file generated for openssl (which is
|
||||
used as the config file)
|
||||
- cert.<unique_name> - output file generated by openssl (which is
|
||||
used as the entry contents)
|
||||
|
||||
openssl signs the provided data, using the TI templated config file and
|
||||
writes the signature in this entry. This allows verification that the
|
||||
data is genuine.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
super().__init__(section, etype, node)
|
||||
self.openssl = None
|
||||
|
||||
def ReadNode(self):
|
||||
super().ReadNode()
|
||||
self.key_fname = self.GetEntryArgsOrProps([
|
||||
EntryArg('keyfile', str)], required=True)[0]
|
||||
self.sha = fdt_util.GetInt(self._node, 'sha', 512)
|
||||
self.req_dist_name = {'C': 'US',
|
||||
'ST': 'TX',
|
||||
'L': 'Dallas',
|
||||
'O': 'Texas Instruments Incorporated',
|
||||
'OU': 'Processors',
|
||||
'CN': 'TI Support',
|
||||
'emailAddress': 'support@ti.com'}
|
||||
|
||||
def GetCertificate(self, required):
|
||||
"""Get the contents of this entry
|
||||
|
||||
Args:
|
||||
required: True if the data must be present, False if it is OK to
|
||||
return None
|
||||
|
||||
Returns:
|
||||
bytes content of the entry, which is the certificate binary for the
|
||||
provided data
|
||||
"""
|
||||
return super().GetCertificate(required=required, type='sysfw')
|
||||
|
||||
def ObtainContents(self):
|
||||
data = self.data
|
||||
if data is None:
|
||||
data = self.GetCertificate(False)
|
||||
if data is None:
|
||||
return False
|
||||
self.SetContents(data)
|
||||
return True
|
||||
|
||||
def ProcessContents(self):
|
||||
# The blob may have changed due to WriteSymbols()
|
||||
data = self.data
|
||||
return self.ProcessContentsUpdate(data)
|
||||
|
||||
def AddBintools(self, btools):
|
||||
super().AddBintools(btools)
|
||||
self.openssl = self.AddBintool(btools, 'openssl')
|
249
tools/binman/etype/ti_secure_rom.py
Normal file
249
tools/binman/etype/ti_secure_rom.py
Normal file
|
@ -0,0 +1,249 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
|
||||
# Written by Neha Malcom Francis <n-francis@ti.com>
|
||||
#
|
||||
|
||||
# Support for generation of TI secured bootloaders booted by ROM
|
||||
|
||||
from binman.entry import EntryArg
|
||||
from binman.etype.x509_cert import Entry_x509_cert
|
||||
|
||||
import hashlib
|
||||
|
||||
from dtoc import fdt_util
|
||||
from u_boot_pylib import tools
|
||||
|
||||
VALID_SHAS = [256, 384, 512, 224]
|
||||
SHA_OIDS = {256:'2.16.840.1.101.3.4.2.1',
|
||||
384:'2.16.840.1.101.3.4.2.2',
|
||||
512:'2.16.840.1.101.3.4.2.3',
|
||||
224:'2.16.840.1.101.3.4.2.4'}
|
||||
|
||||
class Entry_ti_secure_rom(Entry_x509_cert):
|
||||
"""Entry containing a TI x509 certificate binary for images booted by ROM
|
||||
|
||||
Properties / Entry arguments:
|
||||
- keyfile: Filename of file containing key to sign binary with
|
||||
- combined: boolean if device follows combined boot flow
|
||||
- countersign: boolean if device contains countersigned system firmware
|
||||
- load: load address of SPL
|
||||
- sw-rev: software revision
|
||||
- sha: Hash function to be used for signing
|
||||
- core: core on which bootloader runs, valid cores are 'secure' and 'public'
|
||||
- content: phandle of SPL in case of legacy bootflow or phandles of component binaries
|
||||
in case of combined bootflow
|
||||
|
||||
The following properties are only for generating a combined bootflow binary:
|
||||
- sysfw-inner-cert: boolean if binary contains sysfw inner certificate
|
||||
- dm-data: boolean if binary contains dm-data binary
|
||||
- content-sbl: phandle of SPL binary
|
||||
- content-sysfw: phandle of sysfw binary
|
||||
- content-sysfw-data: phandle of sysfw-data or tifs-data binary
|
||||
- content-sysfw-inner-cert (optional): phandle of sysfw inner certificate binary
|
||||
- content-dm-data (optional): phandle of dm-data binary
|
||||
- load-sysfw: load address of sysfw binary
|
||||
- load-sysfw-data: load address of sysfw-data or tifs-data binary
|
||||
- load-sysfw-inner-cert (optional): load address of sysfw inner certificate binary
|
||||
- load-dm-data (optional): load address of dm-data binary
|
||||
|
||||
Output files:
|
||||
- input.<unique_name> - input file passed to openssl
|
||||
- config.<unique_name> - input file generated for openssl (which is
|
||||
used as the config file)
|
||||
- cert.<unique_name> - output file generated by openssl (which is
|
||||
used as the entry contents)
|
||||
|
||||
openssl signs the provided data, using the TI templated config file and
|
||||
writes the signature in this entry. This allows verification that the
|
||||
data is genuine.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
super().__init__(section, etype, node)
|
||||
self.openssl = None
|
||||
|
||||
def ReadNode(self):
|
||||
super().ReadNode()
|
||||
self.combined = fdt_util.GetBool(self._node, 'combined', False)
|
||||
self.countersign = fdt_util.GetBool(self._node, 'countersign', False)
|
||||
self.load_addr = fdt_util.GetInt(self._node, 'load', 0x00000000)
|
||||
self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
|
||||
self.sha = fdt_util.GetInt(self._node, 'sha', 512)
|
||||
self.core = fdt_util.GetString(self._node, 'core', 'secure')
|
||||
self.key_fname = self.GetEntryArgsOrProps([
|
||||
EntryArg('keyfile', str)], required=True)[0]
|
||||
if self.combined:
|
||||
self.sysfw_inner_cert = fdt_util.GetBool(self._node, 'sysfw-inner-cert', False)
|
||||
self.load_addr_sysfw = fdt_util.GetInt(self._node, 'load-sysfw', 0x00000000)
|
||||
self.load_addr_sysfw_data = fdt_util.GetInt(self._node, 'load-sysfw-data', 0x00000000)
|
||||
self.dm_data = fdt_util.GetBool(self._node, 'dm-data', False)
|
||||
if self.dm_data:
|
||||
self.load_addr_dm_data = fdt_util.GetInt(self._node, 'load-dm-data', 0x00000000)
|
||||
self.req_dist_name = {'C': 'US',
|
||||
'ST': 'TX',
|
||||
'L': 'Dallas',
|
||||
'O': 'Texas Instruments Incorporated',
|
||||
'OU': 'Processors',
|
||||
'CN': 'TI Support',
|
||||
'emailAddress': 'support@ti.com'}
|
||||
|
||||
def NonCombinedGetCertificate(self, required):
|
||||
"""Generate certificate for legacy boot flow
|
||||
|
||||
Args:
|
||||
required: True if the data must be present, False if it is OK to
|
||||
return None
|
||||
|
||||
Returns:
|
||||
bytes content of the entry, which is the certificate binary for the
|
||||
provided data
|
||||
"""
|
||||
if self.core == 'secure':
|
||||
if self.countersign:
|
||||
self.cert_type = 3
|
||||
else:
|
||||
self.cert_type = 2
|
||||
self.bootcore = 0
|
||||
self.bootcore_opts = 32
|
||||
else:
|
||||
self.cert_type = 1
|
||||
self.bootcore = 16
|
||||
self.bootcore_opts = 0
|
||||
return super().GetCertificate(required=required, type='rom')
|
||||
|
||||
def CombinedGetCertificate(self, required):
|
||||
"""Generate certificate for combined boot flow
|
||||
|
||||
Args:
|
||||
required: True if the data must be present, False if it is OK to
|
||||
return None
|
||||
|
||||
Returns:
|
||||
bytes content of the entry, which is the certificate binary for the
|
||||
provided data
|
||||
"""
|
||||
uniq = self.GetUniqueName()
|
||||
|
||||
self.num_comps = 3
|
||||
self.sha_type = SHA_OIDS[self.sha]
|
||||
|
||||
# sbl
|
||||
self.content = fdt_util.GetPhandleList(self._node, 'content-sbl')
|
||||
input_data_sbl = self.GetContents(required)
|
||||
if input_data_sbl is None:
|
||||
return None
|
||||
|
||||
input_fname_sbl = tools.get_output_filename('input.%s' % uniq)
|
||||
tools.write_file(input_fname_sbl, input_data_sbl)
|
||||
|
||||
indata_sbl = tools.read_file(input_fname_sbl)
|
||||
self.hashval_sbl = hashlib.sha512(indata_sbl).hexdigest()
|
||||
self.imagesize_sbl = len(indata_sbl)
|
||||
|
||||
# sysfw
|
||||
self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw')
|
||||
input_data_sysfw = self.GetContents(required)
|
||||
|
||||
input_fname_sysfw = tools.get_output_filename('input.%s' % uniq)
|
||||
tools.write_file(input_fname_sysfw, input_data_sysfw)
|
||||
|
||||
indata_sysfw = tools.read_file(input_fname_sysfw)
|
||||
self.hashval_sysfw = hashlib.sha512(indata_sysfw).hexdigest()
|
||||
self.imagesize_sysfw = len(indata_sysfw)
|
||||
|
||||
# sysfw data
|
||||
self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw-data')
|
||||
input_data_sysfw_data = self.GetContents(required)
|
||||
|
||||
input_fname_sysfw_data = tools.get_output_filename('input.%s' % uniq)
|
||||
tools.write_file(input_fname_sysfw_data, input_data_sysfw_data)
|
||||
|
||||
indata_sysfw_data = tools.read_file(input_fname_sysfw_data)
|
||||
self.hashval_sysfw_data = hashlib.sha512(indata_sysfw_data).hexdigest()
|
||||
self.imagesize_sysfw_data = len(indata_sysfw_data)
|
||||
|
||||
# sysfw inner cert
|
||||
self.sysfw_inner_cert_ext_boot_block = ""
|
||||
self.sysfw_inner_cert_ext_boot_sequence_string = ""
|
||||
imagesize_sysfw_inner_cert = 0
|
||||
if self.sysfw_inner_cert:
|
||||
self.content = fdt_util.GetPhandleList(self._node, 'content-sysfw-inner-cert')
|
||||
input_data_sysfw_inner_cert = self.GetContents(required)
|
||||
|
||||
input_fname_sysfw_inner_cert = tools.get_output_filename('input.%s' % uniq)
|
||||
tools.write_file(input_fname_sysfw_inner_cert, input_data_sysfw_inner_cert)
|
||||
|
||||
indata_sysfw_inner_cert = tools.read_file(input_fname_sysfw_inner_cert)
|
||||
hashval_sysfw_inner_cert = hashlib.sha512(indata_sysfw_inner_cert).hexdigest()
|
||||
imagesize_sysfw_inner_cert = len(indata_sysfw_inner_cert)
|
||||
self.num_comps += 1
|
||||
self.sysfw_inner_cert_ext_boot_sequence_string = "sysfw_inner_cert=SEQUENCE:sysfw_inner_cert"
|
||||
self.sysfw_inner_cert_ext_boot_block = f"""[sysfw_inner_cert]
|
||||
compType = INTEGER:3
|
||||
bootCore = INTEGER:0
|
||||
compOpts = INTEGER:0
|
||||
destAddr = FORMAT:HEX,OCT:00000000
|
||||
compSize = INTEGER:{imagesize_sysfw_inner_cert}
|
||||
shaType = OID:{self.sha_type}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval_sysfw_inner_cert}"""
|
||||
|
||||
# dm data
|
||||
self.dm_data_ext_boot_sequence_string = ""
|
||||
self.dm_data_ext_boot_block = ""
|
||||
imagesize_dm_data = 0
|
||||
if self.dm_data:
|
||||
self.content = fdt_util.GetPhandleList(self._node, 'content-dm-data')
|
||||
input_data_dm_data = self.GetContents(required)
|
||||
|
||||
input_fname_dm_data = tools.get_output_filename('input.%s' % uniq)
|
||||
tools.write_file(input_fname_dm_data, input_data_dm_data)
|
||||
|
||||
indata_dm_data = tools.read_file(input_fname_dm_data)
|
||||
hashval_dm_data = hashlib.sha512(indata_dm_data).hexdigest()
|
||||
imagesize_dm_data = len(indata_dm_data)
|
||||
self.num_comps += 1
|
||||
self.dm_data_ext_boot_sequence_string = "dm_data=SEQUENCE:dm_data"
|
||||
self.dm_data_ext_boot_block = f"""[dm_data]
|
||||
compType = INTEGER:17
|
||||
bootCore = INTEGER:16
|
||||
compOpts = INTEGER:0
|
||||
destAddr = FORMAT:HEX,OCT:{self.load_addr_dm_data:08x}
|
||||
compSize = INTEGER:{imagesize_dm_data}
|
||||
shaType = OID:{self.sha_type}
|
||||
shaValue = FORMAT:HEX,OCT:{hashval_dm_data}"""
|
||||
|
||||
self.total_size = self.imagesize_sbl + self.imagesize_sysfw + self.imagesize_sysfw_data + imagesize_sysfw_inner_cert + imagesize_dm_data
|
||||
return super().GetCertificate(required=required, type='rom-combined')
|
||||
|
||||
def GetCertificate(self, required):
|
||||
"""Get the contents of this entry
|
||||
|
||||
Args:
|
||||
required: True if the data must be present, False if it is OK to
|
||||
return None
|
||||
|
||||
Returns:
|
||||
bytes content of the entry, which is the certificate binary for the
|
||||
provided data
|
||||
"""
|
||||
if self.combined:
|
||||
return self.CombinedGetCertificate(required)
|
||||
else:
|
||||
return self.NonCombinedGetCertificate(required)
|
||||
|
||||
def ObtainContents(self):
|
||||
data = self.data
|
||||
if data is None:
|
||||
data = self.GetCertificate(False)
|
||||
if data is None:
|
||||
return False
|
||||
self.SetContents(data)
|
||||
return True
|
||||
|
||||
def ProcessContents(self):
|
||||
# The blob may have changed due to WriteSymbols()
|
||||
data = self.data
|
||||
return self.ProcessContentsUpdate(data)
|
||||
|
||||
def AddBintools(self, btools):
|
||||
super().AddBintools(btools)
|
||||
self.openssl = self.AddBintool(btools, 'openssl')
|
|
@ -31,6 +31,26 @@ class Entry_x509_cert(Entry_collection):
|
|||
def __init__(self, section, etype, node):
|
||||
super().__init__(section, etype, node)
|
||||
self.openssl = None
|
||||
self.req_dist_name = None
|
||||
self.cert_type = None
|
||||
self.bootcore = None
|
||||
self.bootcore_opts = None
|
||||
self.load_addr = None
|
||||
self.sha = None
|
||||
self.total_size = None
|
||||
self.num_comps = None
|
||||
self.sysfw_inner_cert_ext_boot_sequence_string = None
|
||||
self.dm_data_ext_boot_sequence_string = None
|
||||
self.imagesize_sbl = None
|
||||
self.hashval_sbl = None
|
||||
self.load_addr_sysfw = None
|
||||
self.imagesize_sysfw = None
|
||||
self.hashval_sysfw = None
|
||||
self.load_addr_sysfw_data = None
|
||||
self.imagesize_sysfw_data = None
|
||||
self.hashval_sysfw_data = None
|
||||
self.sysfw_inner_cert_ext_boot_block = None
|
||||
self.dm_data_ext_boot_block = None
|
||||
|
||||
def ReadNode(self):
|
||||
super().ReadNode()
|
||||
|
@ -38,13 +58,16 @@ class Entry_x509_cert(Entry_collection):
|
|||
self._cert_rev = fdt_util.GetInt(self._node, 'cert-revision-int', 0)
|
||||
self.key_fname = self.GetEntryArgsOrProps([
|
||||
EntryArg('keyfile', str)], required=True)[0]
|
||||
self.sw_rev = fdt_util.GetInt(self._node, 'sw-rev', 1)
|
||||
|
||||
def GetCertificate(self, required):
|
||||
def GetCertificate(self, required, type='generic'):
|
||||
"""Get the contents of this entry
|
||||
|
||||
Args:
|
||||
required: True if the data must be present, False if it is OK to
|
||||
return None
|
||||
type: Type of x509 certificate to generate, current supported ones are
|
||||
'generic', 'sysfw', 'rom'
|
||||
|
||||
Returns:
|
||||
bytes content of the entry, which is the signed vblock for the
|
||||
|
@ -60,13 +83,61 @@ class Entry_x509_cert(Entry_collection):
|
|||
input_fname = tools.get_output_filename('input.%s' % uniq)
|
||||
config_fname = tools.get_output_filename('config.%s' % uniq)
|
||||
tools.write_file(input_fname, input_data)
|
||||
stdout = self.openssl.x509_cert(
|
||||
cert_fname=output_fname,
|
||||
input_fname=input_fname,
|
||||
key_fname=self.key_fname,
|
||||
cn=self._cert_ca,
|
||||
revision=self._cert_rev,
|
||||
config_fname=config_fname)
|
||||
if type == 'generic':
|
||||
stdout = self.openssl.x509_cert(
|
||||
cert_fname=output_fname,
|
||||
input_fname=input_fname,
|
||||
key_fname=self.key_fname,
|
||||
cn=self._cert_ca,
|
||||
revision=self._cert_rev,
|
||||
config_fname=config_fname)
|
||||
elif type == 'sysfw':
|
||||
stdout = self.openssl.x509_cert_sysfw(
|
||||
cert_fname=output_fname,
|
||||
input_fname=input_fname,
|
||||
key_fname=self.key_fname,
|
||||
config_fname=config_fname,
|
||||
sw_rev=self.sw_rev,
|
||||
req_dist_name_dict=self.req_dist_name)
|
||||
elif type == 'rom':
|
||||
stdout = self.openssl.x509_cert_rom(
|
||||
cert_fname=output_fname,
|
||||
input_fname=input_fname,
|
||||
key_fname=self.key_fname,
|
||||
config_fname=config_fname,
|
||||
sw_rev=self.sw_rev,
|
||||
req_dist_name_dict=self.req_dist_name,
|
||||
cert_type=self.cert_type,
|
||||
bootcore=self.bootcore,
|
||||
bootcore_opts=self.bootcore_opts,
|
||||
load_addr=self.load_addr,
|
||||
sha=self.sha
|
||||
)
|
||||
elif type == 'rom-combined':
|
||||
stdout = self.openssl.x509_cert_rom_combined(
|
||||
cert_fname=output_fname,
|
||||
input_fname=input_fname,
|
||||
key_fname=self.key_fname,
|
||||
config_fname=config_fname,
|
||||
sw_rev=self.sw_rev,
|
||||
req_dist_name_dict=self.req_dist_name,
|
||||
load_addr=self.load_addr,
|
||||
sha=self.sha,
|
||||
total_size=self.total_size,
|
||||
num_comps=self.num_comps,
|
||||
sysfw_inner_cert_ext_boot_sequence_string=self.sysfw_inner_cert_ext_boot_sequence_string,
|
||||
dm_data_ext_boot_sequence_string=self.dm_data_ext_boot_sequence_string,
|
||||
imagesize_sbl=self.imagesize_sbl,
|
||||
hashval_sbl=self.hashval_sbl,
|
||||
load_addr_sysfw=self.load_addr_sysfw,
|
||||
imagesize_sysfw=self.imagesize_sysfw,
|
||||
hashval_sysfw=self.hashval_sysfw,
|
||||
load_addr_sysfw_data=self.load_addr_sysfw_data,
|
||||
imagesize_sysfw_data=self.imagesize_sysfw_data,
|
||||
hashval_sysfw_data=self.hashval_sysfw_data,
|
||||
sysfw_inner_cert_ext_boot_block=self.sysfw_inner_cert_ext_boot_block,
|
||||
dm_data_ext_boot_block=self.dm_data_ext_boot_block
|
||||
)
|
||||
if stdout is not None:
|
||||
data = tools.read_file(output_fname)
|
||||
else:
|
||||
|
|
|
@ -98,6 +98,7 @@ PRE_LOAD_MAGIC = b'UBSH'
|
|||
PRE_LOAD_VERSION = 0x11223344.to_bytes(4, 'big')
|
||||
PRE_LOAD_HDR_SIZE = 0x00001000.to_bytes(4, 'big')
|
||||
TI_BOARD_CONFIG_DATA = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
TI_UNSECURE_DATA = b'unsecuredata'
|
||||
|
||||
# Subdirectory of the input dir to use to put test FDTs
|
||||
TEST_FDT_SUBDIR = 'fdts'
|
||||
|
@ -211,6 +212,7 @@ class TestFunctional(unittest.TestCase):
|
|||
TestFunctional._MakeInputFile('fw_dynamic.bin', OPENSBI_DATA)
|
||||
TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
|
||||
TestFunctional._MakeInputFile('rockchip-tpl.bin', ROCKCHIP_TPL_DATA)
|
||||
TestFunctional._MakeInputFile('ti_unsecure.bin', TI_UNSECURE_DATA)
|
||||
|
||||
# Add a few .dtb files for testing
|
||||
TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
|
||||
|
@ -6905,5 +6907,55 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
|
|||
data = self._DoReadFile('279_ti_board_cfg_no_type.dts')
|
||||
self.assertIn("Schema validation error", str(e.exception))
|
||||
|
||||
def testPackTiSecure(self):
|
||||
"""Test that an image with a TI secured binary can be created"""
|
||||
keyfile = self.TestFile('key.key')
|
||||
entry_args = {
|
||||
'keyfile': keyfile,
|
||||
}
|
||||
data = self._DoReadFileDtb('279_ti_secure.dts',
|
||||
entry_args=entry_args)[0]
|
||||
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
|
||||
|
||||
def testPackTiSecureMissingTool(self):
|
||||
"""Test that an image with a TI secured binary (non-functional) can be created
|
||||
when openssl is missing"""
|
||||
keyfile = self.TestFile('key.key')
|
||||
entry_args = {
|
||||
'keyfile': keyfile,
|
||||
}
|
||||
with test_util.capture_sys_output() as (_, stderr):
|
||||
self._DoTestFile('279_ti_secure.dts',
|
||||
force_missing_bintools='openssl',
|
||||
entry_args=entry_args)
|
||||
err = stderr.getvalue()
|
||||
self.assertRegex(err, "Image 'image'.*missing bintools.*: openssl")
|
||||
|
||||
def testPackTiSecureROM(self):
|
||||
"""Test that a ROM image with a TI secured binary can be created"""
|
||||
keyfile = self.TestFile('key.key')
|
||||
entry_args = {
|
||||
'keyfile': keyfile,
|
||||
}
|
||||
data = self._DoReadFileDtb('280_ti_secure_rom.dts',
|
||||
entry_args=entry_args)[0]
|
||||
data_a = self._DoReadFileDtb('288_ti_secure_rom_a.dts',
|
||||
entry_args=entry_args)[0]
|
||||
data_b = self._DoReadFileDtb('289_ti_secure_rom_b.dts',
|
||||
entry_args=entry_args)[0]
|
||||
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
|
||||
self.assertGreater(len(data_a), len(TI_UNSECURE_DATA))
|
||||
self.assertGreater(len(data_b), len(TI_UNSECURE_DATA))
|
||||
|
||||
def testPackTiSecureROMCombined(self):
|
||||
"""Test that a ROM image with a TI secured binary can be created"""
|
||||
keyfile = self.TestFile('key.key')
|
||||
entry_args = {
|
||||
'keyfile': keyfile,
|
||||
}
|
||||
data = self._DoReadFileDtb('281_ti_secure_rom_combined.dts',
|
||||
entry_args=entry_args)[0]
|
||||
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
17
tools/binman/test/279_ti_secure.dts
Normal file
17
tools/binman/test/279_ti_secure.dts
Normal file
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
ti-secure {
|
||||
content = <&unsecure_binary>;
|
||||
};
|
||||
unsecure_binary: blob-ext {
|
||||
filename = "ti_unsecure.bin";
|
||||
};
|
||||
};
|
||||
};
|
17
tools/binman/test/280_ti_secure_rom.dts
Normal file
17
tools/binman/test/280_ti_secure_rom.dts
Normal file
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
ti-secure-rom {
|
||||
content = <&unsecure_binary>;
|
||||
};
|
||||
unsecure_binary: blob-ext {
|
||||
filename = "ti_unsecure.bin";
|
||||
};
|
||||
};
|
||||
};
|
25
tools/binman/test/281_ti_secure_rom_combined.dts
Normal file
25
tools/binman/test/281_ti_secure_rom_combined.dts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
ti-secure-rom {
|
||||
content = <&unsecure_binary>;
|
||||
content-sbl = <&unsecure_binary>;
|
||||
content-sysfw = <&unsecure_binary>;
|
||||
content-sysfw-data = <&unsecure_binary>;
|
||||
content-sysfw-inner-cert = <&unsecure_binary>;
|
||||
content-dm-data = <&unsecure_binary>;
|
||||
combined;
|
||||
sysfw-inner-cert;
|
||||
dm-data;
|
||||
};
|
||||
unsecure_binary: blob-ext {
|
||||
filename = "ti_unsecure.bin";
|
||||
};
|
||||
};
|
||||
};
|
19
tools/binman/test/288_ti_secure_rom_a.dts
Normal file
19
tools/binman/test/288_ti_secure_rom_a.dts
Normal file
|
@ -0,0 +1,19 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
ti-secure-rom {
|
||||
content = <&unsecure_binary>;
|
||||
core = "secure";
|
||||
countersign;
|
||||
};
|
||||
unsecure_binary: blob-ext {
|
||||
filename = "ti_unsecure.bin";
|
||||
};
|
||||
};
|
||||
};
|
18
tools/binman/test/289_ti_secure_rom_b.dts
Normal file
18
tools/binman/test/289_ti_secure_rom_b.dts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
ti-secure-rom {
|
||||
content = <&unsecure_binary>;
|
||||
core = "public";
|
||||
};
|
||||
unsecure_binary: blob-ext {
|
||||
filename = "ti_unsecure.bin";
|
||||
};
|
||||
};
|
||||
};
|
Loading…
Reference in a new issue