Masterboot image with Signature Provider

This notebook describes how to use a custom remote signing service for generating masterboot image using nxpimage tool.

[1]:
%run ../init_notebook.ipynb

import pprint
import os

pp = pprint.PrettyPrinter(indent=4)

plugins_dir = 'plugins/'

SASP_PLUGIN = os.path.join(plugins_dir, 'sasp.py')
WORKSPACE = "workspace/mbimg/" # change this to path to your workspace
DATA_DIR = "data_mbimg/" # change this to path to your workspace
VERBOSITY = "-v" # verbosity of commands, might be -v or -vv for debug or blank for no additional info
env: JUPYTER_SPSDK=1
Created `%!` as an alias for `%execute`.

Signature Provider Plugin

First, we need to setup the Signature Provider plugin and start the custom HSM. In order to do that, open this notebook and follow the instructions there. Once you are done, come back and continue here.

Config File Setup

The masterboot configuration file will be needed for successful generation of Masterboot image(MBI) using nxpimage application. * There are three types of MBI for RT5xx based on the authentication type: Plain, CRC and Signed.

In this example we will be interested only in the Signed image type.

Run the following code and see how the generated configuration template looks like.

[1]:
import yaml
import os
import shutil
from spsdk.utils.misc import load_configuration, load_file
# choose family for the MCU
FAMILY = "rt5xx"

%! nxpimage $VERBOSITY mbi get-templates --family $FAMILY --output $WORKSPACE --force

CONFIG_PATH = os.path.join(WORKSPACE, "rt5xx_xip_signed.yaml")
# just for verification that the template was generated
assert os.path.exists(CONFIG_PATH)

config_content = load_file(CONFIG_PATH)
print(config_content)
nxpimage -v mbi get-templates --family rt5xx --output workspace/mbimg/ --force
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_xip_plain.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_xip_crc.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_xip_signed.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_load_to_ram_plain.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_load_to_ram_crc.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_load_to_ram_signed.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\rt5xx_signature_provider\workspace\mbimg\rt5xx_load_to_ram_encrypted.yaml template file.
# ===================  Master Boot Image Configuration template for rt5xx, Plain Signed XIP Image.  ====================

# ======================================================================================================================
#                                                  == Basic Settings ==
# ======================================================================================================================
# ------------------------------------------===== MCU family [Required] =====-------------------------------------------
# Description: MCU family name.
# Possible options: <lpc55s0x, lpc55s1x, rt5xx, rt6xx>
family: rt5xx
# --------------------------------------===== Application target [Required] =====---------------------------------------
# Description: Definition if application is Execute in Place(XiP) or loaded to RAM during reset sequence.
# Possible options: <xip, load-to-ram>
outputImageExecutionTarget: xip
# -------------------------------===== Type of boot image authentication [Required] =====-------------------------------
# Description: Specification of final master boot image authentication.
# Possible options: <plain, crc, signed, signed-encrypted, signed-nxp>
outputImageAuthenticationType: signed
# ------------------------------------===== Master Boot Image name [Required] =====-------------------------------------
# Description: The file for Master Boot Image result file.
masterBootOutputFile: my_mbi.bin
# ------------------------------------===== Plain application image [Required] =====------------------------------------
# Description: The input application image to by modified to Master Boot Image.
inputImageFile: my_application.bin
# --------------------------------===== Loading address of application [Required] =====---------------------------------
# Description: Application loading address in RAM if not XiP, otherwise address of load in XiP.
outputImageExecutionAddress: 0
# ----------------------------------===== Enable User HW key sharing [Required] =====-----------------------------------
# Description: Controlling secure hardware key bus. If enabled(1), then it is possible to access keys on hardware secure
# bus from non-secure application, else non-secure application will read zeros.
enableHwUserModeKeys: false
# ======================================================================================================================
#                                               == Trust Zone Settings ==
# ======================================================================================================================
# ------------------------------------===== TrustZone enable option [Optional] =====------------------------------------
# Description: If not specified, the Trust zone is disabled.
enableTrustZone: false
# ---------------------------------===== TrustZone Customization file [Optional] =====----------------------------------
# Description: If not specified, but TrustZone is enabled(enableTrustZone) the default values are used.
trustZonePresetFile: my_tz_custom.yaml
# ======================================================================================================================
#                                               == Certificate Block V1 ==
# ======================================================================================================================
# -----------------------------===== Certificate Block binary/config file [Required] =====------------------------------
# Description: Path to certificate block binary or config file.
certBlock: cert_block.yaml
# ======================================================================================================================
#                                              == Image Signing Settings ==
# ======================================================================================================================
# --------------------------===== Main Certificate private key [Conditionally required] =====---------------------------
# Description: Main Certificate private key used to sign certificate. It can be replaced by signProvider key.
signPrivateKey: main_prv_key.pem
# -------------------------------===== Signature Provider [Conditionally required] =====--------------------------------
# Description: Signature provider configuration in format 'type=<sp_type>;<key1>=<value1>;<key2>=<value2>".
signProvider: type=file;file_path=my_prv_key.pem

The generated configuration file contains all possible configuration settings.

Some of them are required (labeled with [Required] comment), some of them are conditionally required (labeled with [Conditionally required] comment) and some are optional (labeled with [Optional] comment).

Let’s now focus on two configuration settings: mainCertPrivateKeyFile and signProvider. These two configuration values are mutually exclusive, so only one can be chosen. In order to use Signature Provider, we will remove the line with mainCertPrivateKeyFile and update the one with signProvider.

Keep in mind that the signature provider configuration must meet following rules: - Configuration key - key names sign_provider or signProvider are allowed

  • Configuration value

    • format "type=<sp_type>;<key1>=<value1>;<key2>=<value2>;..."

    • the sp_type has to match the sp_type class attribute defined in the custom signature provider(plugins/sasp.py)

    • the remaining key-value pairs are passed to the __init__ method of the concrete Signature Provider

    • e.g.: "type=file;file_path=private_key.pem" will instantiate spsdk.crypto.PlainFileSP(file_path='private_key.pem')

Run the code bellow so you keep only configuration settings related to this example.

[1]:
# We will create a config file containing only settings we need for this example
# Create certificate block configuration first
cert_block_config = {'imageBuildNumber': 0, 'mainRootCertId': 0, 'rootCertificate0File': 'root_k0_signed_cert0_noca.der.cert', 'containerOutputFile': 'cert_block.bin'}
with open(os.path.join(WORKSPACE, "cert_block.yaml"), 'w') as file:
    yaml.dump(cert_block_config, file, default_flow_style=False)

# Now let's create the actual MBI configuration
# Just remember to use signProvider for remote signing
config = {'family': 'rt5xx', 'inputImageFile': 'my_application.bin',  'masterBootOutputFile': 'my_mbi.bin', 'outputImageAuthenticationType': 'signed',
          'outputImageExecutionAddress': 0, 'outputImageExecutionTarget': 'xip', 'enableHwUserModeKeys': False, 'enableTrustZone': False,
          'signProvider': 'type=sasp;key_number=0', 'certBlock': 'cert_block.yaml'}
with open(CONFIG_PATH, 'w') as file:
    yaml.dump(config, file, default_flow_style=False)

# Copy additional files needed for masterboot image creation
files_needed = ['my_application.bin', 'root_k0_signed_cert0_noca.der.cert']
for file in files_needed:
    shutil.copyfile(os.path.join(DATA_DIR, file), os.path.join(WORKSPACE, file))

pp.pprint(f"All files are ready in folder '{WORKSPACE}'")
"All files are ready in folder 'workspace/mbimg/'"

Execution

At this point, we have everything we need to run nxpimage application using remote HSM for image signing.

[1]:
%! nxpimage $VERBOSITY mbi export --plugin $SASP_PLUGIN --config $CONFIG_PATH

# check if the signed image exists
output_file = os.path.join(WORKSPACE, config['masterBootOutputFile'])
assert os.path.exists(output_file)
nxpimage -v mbi export --plugin plugins/sasp.py --config workspace/mbimg/rt5xx_xip_signed.yaml
RKTH: db31d46c717711a8231cbc38b1de8a6e8657e1f733e04c2ee4b62fcea59149fa
Success. (Master Boot Image: C:/spsdk/examples/jupyter_examples/rt5xx_signature_provider/workspace/mbimg/my_mbi.bin created.)

HSM teardown

Last step is to stop custom HSM. In order to do that, open again the notebook and stop the running jupyter notebook code cell.