5 Step by Step Guide

Detailed instructions for each provisioning step from key generation through device programming.

Step 1: Generate / Load Secure Boot Key

Methodgenerate_resources
PrerequisiteNone (first step)
RepeatableNo -- slot 2 is fixed; shows warning if already loaded

What it does:

  1. Connects to the Secure Element via USB HID kit-protocol.

  2. Discovers the HSMLITE device on the board. If the factory kit firmware is not programmed, it programs it automatically and asks the user to reset the board.

  3. Generates or loads an ECC P-256 key pair for firmware signing.

  4. Registers the key in VSS slot 2 (the HSM secure boot signing slot -- fixed, not user-selectable).

Key generation dialog:

OptionDescription
Generate Private/Public keypair (TPDS)Creates a new ECC P-256 key pair using the TPDS TPAsymmetricKey library (software generation)
Upload Private key from fileLoads an existing private key from a .pem file. The public key is derived automatically.

Output files:

FileContent
private_key_slot2.pemECC P-256 private key (PKCS#8 PEM)
public_key_slot2.pemECC P-256 public key (SubjectPublicKeyInfo PEM)
Important: This key is the signing key used to sign the FWMD. It is always emitted in the VSS regardless of the checkbox selection in Step 3.

Step 1a: PUF Enrollment

Methodpuf_enrollment
PrerequisiteStep 1 (board must be connected)
RepeatableYes, but only needed once per device

What it does:

  1. Requests a PUF Activation Code (996 bytes) from the PUF hardware via the kit-protocol command.

  2. Saves the activation code as PIC32CMSG_PUF_AC.hex (Intel HEX format) at address 0x0A003C00.

PUF enrollment only needs to be performed once per device. If the PUF has already been enrolled (the hex file exists), a dialog will inform the user and ask whether to re-enroll.

Automatic PUF AC reload: If Step 1b or 1c is executed later without Step 1a having run in this session, the tool will automatically:

  1. Load the PUF AC from the saved PIC32CMSG_PUF_AC.hex file.

  2. Send it to the device via the kit-protocol command.

  3. Verify the echoed response matches the original data.

Step 1b: Generate / Load Additional User Keys (Repeatable)

Methodgenerate_user_key
PrerequisiteStep 1 (board must be connected)
RepeatableYes -- up to 10 keys total (including the Step 1 key)

What it does:

Adds additional keys to the internal key registry. Each execution adds one key. This step presents a two-level dialog:

First dialog: PUF or not?

OptionDescription
Yes - Generate with PUFGenerates an ECC P-256 key pair. PUF generates a key which is considered a "private" key. This "private" key is sent to the TPDS software and the public key is then derived from it by TPDS using ECC algorithm. Requires Step 1a (PUF enrollment). Wrapping is NOT done here -- it is deferred to Step 1c.
No - Generate/Load without PUFOpens the key-type selection dialog (see below). Supports both asymmetric and symmetric keys, generated via software or loaded from file.

Second dialog (non-PUF path): Key type selection.

OptionDescription
Asymmetric (ECC P-256)Generate a new key pair with TPDS software, or load from a .pem file
Symmetric (AES)Load a raw AES-128 or AES-256 key. Sub-dialog asks for key size, then input method (file or manual hex entry).

Third dialog: Slot index.

After selecting the key type, the user is asked to choose a VSS slot index (2-127) where this key will be stored. The dialog shows which slots are already in use. Duplicate slots are rejected.

Output files (per key):

Key TypeFiles Generated
Asymmetric (TPDS)private_key_slot{N}.pem, public_key_slot{N}.pem
Asymmetric (PUF)private_puf_key_slot{N}.pem, public_puf_key_slot{N}.pem
Symmetric (AES 128)symmetric_key_slot{N}_aes128.pem
Symmetric (AES 256)symmetric_key_slot{N}_aes256.pem

Example session (loading 3 keys):

Click 1b -->  "No - Generate/Load without PUF"
              "Asymmetric (ECC P-256)"
              Slot: 3
              "Generate Private/Public keypair (TPDS)"
              --> Key registered in slot 3

Click 1b -->  "Yes - Generate with PUF"
              Slot: 5
              --> PUF key generated, registered in slot 5

Click 1b -->  "No - Generate/Load without PUF"
              "Symmetric (AES)"
              "AES-256 (32 bytes)"
              Slot: 10
              "Load from hex file"
              --> AES-256 key registered in slot 10
      

After these 3 executions plus Step 1, the registry contains 4 keys (slots 2, 3, 5, 10).

Step 1c: Wrap All Keys With PUF

Methodpuf_wrap_all_keys
PrerequisiteStep 1a (PUF enrollment must be completed)
RepeatableYes (idempotent -- skips already-wrapped keys)
Important: Highly recommended. This step is critical for production deployments. When key codes (PUF-wrapped keys) are stored in the VSS instead of plain keys, the original key material does not need to be stored anywhere -- neither on the device nor off-device. The application firmware can recover the keys at runtime by unwrapping the key codes through the PUF hardware. Because the PUF wrapping is device-unique, the key codes are useless on any other chip, providing strong protection against Flash readout attacks and cloning. If Step 1c is skipped and plain keys are stored in the VSS instead, an attacker who can read the Flash contents obtains the raw key material directly. Step 1c is a prerequisite for Step 3 in any security-sensitive deployment.

What it does:

Iterates the entire key registry and wraps every key that does not already have a key code, using the PUF hardware via the kit-protocol command.

Wrapping rules:

Key TypeWhat Gets WrappedKey Code Field
AsymmetricPrivate key only (public key can be derived)keycode_prv
SymmetricFull key datakeycode

Skip conditions (per key):

  • Already has a key code (keycode_prv or keycode is not None)

  • No key material available (e.g., private key is None)

Key code slot convention (demo only):

keycode_slot = 0x80 | original_slot
      
  • Bit 7 (0x80) = key code flag

  • Bits [6:0] = original slot index

Note: This 0x80 | original_slot convention is used for demonstration purposes only, so that the LED demo application provided in this use case can locate and unwrap key codes to compare them against the original keys. In a production deployment, slots 3-255 are freely available for both keys and key codes, and users can assign any slot number according to their own requirements.

Example: A key in slot 5 produces a key code in slot 0x85 (133).

Output files: For each wrapped key in slot N:

Key TypeFile
Asymmetric (private key)slot{N}_privkey_keycode.txt
Symmetric`slot{N}_{aes128

Console output example:

STEP 1c: Wrap all registered keys with PUF
  Slot   2: Wrapping private key (ECC P-256 (GEN_TPDS_PRVKEY))...
           Key code saved to slot2_privkey_keycode.txt
  Slot   3: Wrapping private key (ECC P-256 (GEN_TPDS_PRVKEY))...
           Key code saved to slot3_privkey_keycode.txt
  Slot   5: Wrapping private key (PUF ECC P-256 Key Pair)...
           Key code saved to slot5_privkey_keycode.txt
  Slot  10: Wrapping symmetric key (AES256 key)...
           Key code saved to slot10_aes256_keycode.txt

Wrap summary: 4 wrapped, 0 skipped
  Slot   2: ECC P-256 (GEN_TPDS_PRVKEY) [wrapped]
  Slot   3: ECC P-256 (GEN_TPDS_PRVKEY) [wrapped]
  Slot   5: PUF ECC P-256 Key Pair [wrapped]
  Slot  10: AES256 key [wrapped]
Executed Step 1c Successfully
      

If executed again (idempotent):

STEP 1c: Wrap all registered keys with PUF
  Slot   2: ECC P-256 (GEN_TPDS_PRVKEY) -- already wrapped, skipping
  Slot   3: ECC P-256 (GEN_TPDS_PRVKEY) -- already wrapped, skipping
  Slot   5: PUF ECC P-256 Key Pair -- already wrapped, skipping
  Slot  10: AES256 key -- already wrapped, skipping

Wrap summary: 0 wrapped, 4 skipped
      

Key code size depends on the key length:

Key TypeKey Length (bytes)Key Code Size (bytes)
ECC P-256 private3284
AES-1281668
AES-2563284

Formula: keyCodeSize = 36 + keyLen + 16 * ceil(keyLenBits / 384).

Step 2: Load Application Image

Methodload_custom_application
PrerequisiteStep 1
RepeatableYes (replaces previous selection)
Note: For first-time users: When the file dialog opens, select one of the two provided LED demo variants (located in the working directory ~/.trustplatform/pic32cmsg_secureboot/):
  • pic32cmsg_led_app_dice.X.production.unified.hex — Device Identifier Composition Engine (DICE) enabled (Compound Device Identifier (CDI) and FW Hash shown on console)
  • pic32cmsg_led_app_nodice.X.production.unified.hex — DICE disabled (standard demo)

Both are built from the same source code with different fuse configurations (BOOT_FLAG_DICEDIS = CLEAR vs. SET). They both demonstrate secure boot, PUF key verification, and VSS keystore reading.

What it does:

  1. Opens a file dialog to select a custom application .hex file.

  2. Extracts per-region hex slices (Boot ROM, Boot Config) from the selected hex file.

  3. Prepares the hex file segments for the FWMDT.

The user can select any compatible application hex file. The LED demo variants above are provided as reference and validation tools.

Regions extracted:

RegionAddress RangeSkip Logic
bootrom0x08000000 - 0x08003FFFExtracted from app hex
bootcfg10x0A002800 - 0x0A002FFFStart shifted +0x800 to skip FWMD area
bootcfg1a0x0A000800 - 0x0A000FFFStart shifted +0x800 to skip FWMD area
romcfgSkippedUses template (DAL = 2)
pufacSkippedGenerated by Step 1a
appSkippedFull hex used directly

Step 3: Execute Firmware Metadata Tool

Methodexecute_fwmdt
PrerequisiteSteps 1, 1a, and 2
RepeatableYes

What it does:

  1. BOOTCFG region selection: prompts for the region where the FWMD will be placed:

    RegionFWMD AddressBOOTCFG Address
    BOOTCFG1 (default)0x0A0020000x0A002800
    BOOTCFG1A0x0A0000000x0A000800
  2. Memory region summary: displays a window showing all addresses that will be included in the metadata.

  3. VSS content selection: displays a checkbox dialog (see VSS Content section) to choose which key material to include in the VSS.

  4. Updates XML files: populates PIC32CMSG_fwmd.xml (image addresses and file paths) and PIC32CMSG_sfp.xml (signing key, VSS variable slots) from the key registry.

  5. Runs hsmsfmdgen.exe: computes SHA-256 hashes of all image segments, signs the FWMD with the signing key (slot 2), and generates the output hex files.

Output files:

FileDescription
pic32cmsg_fwmd.hexCombined image: FWMD + Boot ROM + Boot Config + ROM Config + PUF AC + Application
pic32cmsg_sfp.hexVSS data consumed by the ROM Boot process

Step 4: Combine Images

Methodcombine_images
PrerequisiteStep 3
RepeatableYes

What it does:

Merges pic32cmsg_fwmd.hex and pic32cmsg_sfp.hex into a single file: pic32cmsg_secure_boot.hex using IntelHex.merge(overlap='error').

This combined hex is ready to be programmed onto the device.

Step 4a: Disable Secure Boot (Optional)

Methoddisable_secureboot
PrerequisiteStep 3
RepeatableYes

What it does:

  1. Modifies the SFP XML to set:

    1. lifecycleState = open.

    2. secureBootConfiguration = disabled.

  2. Regenerates the FWMD and SFP hex files.

  3. Combines them into pic32cmsg_secure_boot_disabled.hex.

This is useful for development and debugging when signature verification is not desired.

Note: the DICE app cannot be used when Secure Boot is disabled because:
  • DICE runs as part of the secure boot chain
  • The generation of the UDS/CDI and derived identities only happens when the Boot ROM enters the Secure Boot flow

Step 5: Program Device

Methodprogram_device
PrerequisiteStep 4
RepeatableYes

What it does:

Programs the combined hex image (pic32cmsg_secure_boot.hex or the disabled variant) onto the PIC32CMSG00 device using MPLAB X IPE (FlashProgram). After programming, the device will reset and the Boot ROM will perform the secure boot sequence.

Expected Output (LED Demo Application with DICE enable).

After Step 5 completes successfully with the LED demo application (pic32cmsg_led_app_dice.X.production.unified.hex), the following behavior confirms a successful provisioning:

Board behavior:

  • The board resets automatically after programming completes

  • LED1 blinks (heartbeat indicating the application is running)

  • SW0 button press turns on LED0

Serial terminal output (115200-8-N-1):

Figure 5-1. Retrieved Secure Example Keys From VSS Page

Figure 5-2. Retrieved Secure Example Key Codes From VSS Page

Figure 5-3. Unwrap Key Codes and Compare With Example Keys
Note: The exact output may vary depending on which keys were provisioned and which VSS content checkboxes were selected in Step 3. The example above shows the minimal secure boot flow (Scenario A).

Reprogramming a Secured Device

If Step 4a was not executed (secure boot remains enabled), the device will enforce signature verification on every boot. This section explains how to reprogram or recover the board.

Reprogram with a New Application Image.

The signing key is preserved across sessions in the project output folder as private_key_slot2.pem. To update the application:

  1. Re-run Step 2 with the new application .hex file.

  2. Re-run Steps 3> 4>5 (using the same signing key from Step 1).

The new image will be signed with the same key and the device will accept it.

Return to Unsecured State (Factory Reset).

To completely remove secure boot and return the device to an open state:

  1. Open MPLAB X IPE (or use the debugger).

  2. Perform a Chip Erase operation.

  3. This erases all Flash including FWMD, VSS, and Boot Configuration.

  4. The device returns to DAL = 2 (open/unsecured) state.

  5. The user can reprogram the board with any unsigned image.

Important: Running this TPDS use case with secure boot enabled does NOT permanently lock or brick the board. A Chip Erase always recovers the device to its factory-open state.

Summary:

SituationActionResult
Update app with same keyRe-run Steps 2>3>4>5New signed image boots normally
Lost the signing keyChip Erase via MPLAB X IPEDevice returns to open state
Want to disable secure bootRun Step 4a, then Step 5Device boots without verification
Board appears brickedChip Erase via MPLAB X IPEFull recovery, DAL = 2 restored