Masterboot image with Signature Provider for rt5xx

Masterboot image with Signature Provider for rt5xx#

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

%run ../../init_notebook.ipynb

import pprint
import os

pp = pprint.PrettyPrinter(indent=4)

plugins_dir = '../common/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 Signature Provider (signature_provider.ipynb) 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.

import os
from spsdk.utils.misc import 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\signature_provider\rt5xx\workspace\mbimg\rt5xx_xip_plain.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\workspace\mbimg\rt5xx_xip_crc.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\workspace\mbimg\rt5xx_xip_signed.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\workspace\mbimg\rt5xx_load_to_ram_plain.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\workspace\mbimg\rt5xx_load_to_ram_crc.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\workspace\mbimg\rt5xx_load_to_ram_signed.yaml template file.
Creating C:\spsdk\examples\jupyter_examples\signature_provider\rt5xx\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.
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: signPrivateKey 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 signPrivateKey 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 use only configuration settings related to this example.

import shutil
# Copy additional files needed for masterboot image creation
shutil.rmtree(WORKSPACE)
shutil.copytree(DATA_DIR, WORKSPACE)

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.

%! nxpimage $VERBOSITY mbi export --plugin $SASP_PLUGIN --config $CONFIG_PATH

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

HSM teardown#

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