> Markdown version of https://docs.laavat.io/usage/signing-encryption/mcuboot-signing/ from the LAAVAT PKI and Signing Platform documentation. All pages: https://docs.laavat.io/llms.txt

# MCUboot Signing

> **Tip: Looking for a complete MCUboot design?**
> This page documents every `request.json` field. For a full secure boot
> chain built on it, see
> [Building CRA-ready nRF devices](https://docs.laavat.io/solutions/cra-ready-nrf/) or
> [Building CRA-ready STM32H5 controllers](https://docs.laavat.io/solutions/cra-ready-stm32h5/).

In order to do MCUboot signing/encryption following actions/configurations are required

* Product is created with a configuration which supports MCUboot signing & encryption.

## Input data for MCUboot signing

Input data is a gzipped tar file containing a configuration `request.json` file and other input files. Multiple images might be generated by a single signing operation. Most JSON fields are mandatory as they are always required for MCUboot imgtool.

Supported options from imgtool:

| Option | JSON data type | Required | Comment |
| --- | --- | --- | --- |
| align | String | Yes |  1, 2, 4 or 8. |
| version | String | Yes | Firmware version, for example 1.6.44+1628771740. |
| header_size | String | Yes | Header size, for example 0x200. |
| slot_size | String | Yes | Size of the slot. If the slots have different sizes, use the size of the secondary slot. |
| pad_header | Boolean | No | Add `header_size` zeroed bytes at the beginning of the image. |
| security_counter | String | No | Specify the value of security counter. Use the `auto` keyword to automatically generate it from the image version. |

| Option | JSON data type | Required | Comment |
| --- | --- | --- | --- |
| boot_record | String | No | Create CBOR encoded boot record TLV. The sw_type represents the role of the software component (e.g. CoFM for coprocessor firmware). [max. 12 characters]. |
| public_key_format | String | No | In what format to add the public key to the image manifest: full key or hash of the key. Allowed values `[hash|full]`. `full` is default.|
| pad | Boolean | No | Pad image to `slot_size` bytes, adding trailer magic. Default value is true. |
| confirm | Boolean | No | When padding the image, mark it as confirmed (implies `pad`).|
| max_sectors | String | No | When padding allow for this amount of sectors (defaults to 128). String value is converted to integer value. |
| overwrite_only | Boolean | No | Use overwrite-only instead of swap upgrade. |
| max_align | String | No | Maximum flash alignment. Set if flash alignment of the primary and secondary slot differ and any of them is larger than 8. Allowed values `[8|16|32]`. |
| save_enctlv | Boolean | No |  When upgrading, save encrypted key TLVs instead of plain keys. Enable when BOOT_SWAP_SAVE_ENCTLV config option was set. |
| load_addr | String | No | Load address for image when it should run from RAM. |
| hex_addr | String | No | Adjust address in hex output file. |
| encrypt | Boolean | No | Encrypt the image with the AES key created in EncryptMcuBoot operation |
| encrypt_keylen | String | No | Optional. When encrypting the image using AES this option can be used to override the token length. Only usefull if user wants to use first 128 bits from the 256 bit token. If token bit lenght is 256 and encrypt_keylen is 128 an error is returned.  If this option is not present the actual token lenght is used. Allowed values `[128|256]`. |
| clear | Boolean | No | Output a non-encrypted image with encryption capabilities,so it can be installed in the primary slot, and encrypted when swapped to the secondary.|

`request.json`:

```json
{
  "images": [
  {
     "filename": "app-1-6-44-1628771740.hex",
     "output": "signed-app-1-6-44-1628771740.hex",
     "align": "4",
     "version": "1.6.44+1628771740",
     "header_size": "0x200",
     "slot_size": "0xea000",
     "pad_header": true
    },
    {
      "filename": "app-1-6-44-1628771740.hex",
      "output": "signed-app-1-6-44-1628771740-scauto.bin",
      "align": "4",
      "version": "1.6.44+1628771740",
      "header_size": "0x200",
      "slot_size": "0xea000",
      "pad_header": true,
      "security_counter": "auto"
    },
    {
      "filename": "app-1-6-44-1628771740.hex",
      "output": "signed-app-1-6-44-1628771740-sc.bin",
      "align": "4",
      "version": "1.6.44+1628771740",
      "header_size": "0x200",
      "slot_size": "0xea000",
      "pad_header": true,
      "security_counter": "0x3ff2"
    },
    {
      "filename": "app-1-6-44-1628771740.hex",
      "output": "signed-app-1-6-44-1628771740.bin",
      "align": "4",
      "version": "1.6.44+1628771740",
      "header_size": "0x200",
      "slot_size": "0xea000",
      "pad_header": true,
      "security_counter": "0x3ff2",
      "pad": false,
      "confirm": true,
      "overwrite_only": true,
      "max_align": "8",
      "public_key_format": "full",
      "boot_record": "SDE",
      "max_sectors": "128",
      "save_enctlv": true,
      "load_addr": "0x3ff2",
      "hex_addr": "0x3ff2",
      "erased_val": "0"
    },
	{
	"filename": "tfm_s_zephyr_ns.hex",
	"output": "tfm_s_zephyr_ns_encrypted.hex",
	"header_size": "0x400",
	"align": "16",
	"slot_size": "0x1a0000",
	"version": "0.1.0+1234567",
	"security_counter": "auto",
	"pad": true,
	"pad_header": true,
	"boot_record": "SPE",
	"public_key_format": "full",
	"encrypt": true,
	"encrypt_keylen": "256"
	}
  ]
}
```

Example of tfm_zephyr_mcuboot_enc payload

```bash
$ tar -tvf tfm_zephyr_mcuboot_enc.tar.gz
-rw-rw-r--  1 vagrant vagrant    1944 Apr 26  2024 request.json
-rwxrwxr-x  1 vagrant vagrant 2856046 Nov 20  2023 tfm_s_zephyr_ns.hex
```

## Output data 

The output download is already in compressed tar format. See example below.

### Example response with validation

The public key used for verification can be obtained using the [client functionality](https://docs.laavat.io/usage/clientguide/clients/#example-of-decrypted-product-secrets)

```bash
(venv) $ signing-tool -n test.ini \
  secrets get -P <Product ID> \
  -C client.private -O /tmp/prod.json
Full secret payload written to: /tmp/prod.json
```

Then extract the Public key of the signing operation

```bash
$ jq -r .tokenInfo[0].publicKey < /tmp/prod.json \ 
| base64 -d | openssl ec -pubin -inform der > /tmp/pub.pem
```

Check the signature:

```bash
$ mkdir -p /tmp/response
$ tar -xvf response.tar.gz -C /tmp/response
$ ls /tmp/response
tfm_s_zephyr_ns_cleared.hex
tfm_s_zephyr_ns_encrypted.hex
tfm_s_zephyr_ns_signed.hex
tfm_s_zephyr_ns_confirmed.hex

$ imgtool verify --key /tmp/pub.pem /tmp/response/tfm_s_zephyr_ns_cleared.hex
Verifying: /tmp/response/tfm_s_zephyr_ns_cleared.hex
Image was correctly validated
Image version: 0.1.0+1234567
Image digest: b1bcbde83c90be004c9936efefb91234cc3dbd84b6841849b26b533e4ad9c0cb

$ imgtool verify --key /tmp/pub.pem /tmp/response/tfm_s_zephyr_ns_encrypted.hex
Verifying: /tmp/response/tfm_s_zephyr_ns_encrypted.hex
Image was correctly validated
Image version: 0.1.0+1234567
Image digest: b1bcbde83c90be004c9936efefb91234cc3dbd84b6841849b26b533e4ad9c0cb

$ imgtool verify --key /tmp/pub.pem/tmp/response/tfm_s_zephyr_ns_signed.hex
Verifying: /tmp/response/tfm_s_zephyr_ns_signed.hex
Image was correctly validated
Image version: 0.1.0+1234567
Image digest: b1bcbde83c90be004c9936efefb91234cc3dbd84b6841849b26b533e4ad9c0cb

$ imgtool verify --key /tmp/pub.pem /tmp/response/tfm_s_zephyr_ns_confirmed.hex
Verifying: /tmp/response/tfm_s_zephyr_ns_confirmed.hex
Image was correctly validated
Image version: 0.1.0+1234567
Image digest: b1bcbde83c90be004c9936efefb91234cc3dbd84b6841849b26b533e4ad9c0cb
```

## Example usage with reference client package: MCUboot signing

MCUboot signing examples. These use two config files created with `config-init`: `test.ini` for the regular user and `approver.ini` for a user in the approvers group. Each config references a `token_file` rather than embedding a token, so no token appears on the command line — see [Reference Client › Usage](https://docs.laavat.io/democlient/usage/) for how to create them and for the secure token-input forms (`-t @file`, `-t @-`).

```bash
(venv) $ signing-tool -n test.ini \
    imagesigning add MCUBoot \
    -N test -D test2 -P adcb30d8-f009-438e-b1b2-96f507b306cb \
    --operid 4add90e9-ffb3-4708-9554-ed2e82e8fd71 -F tfm_zephyr_mcuboot_enc.tar.gz

# Approve the mcuboot signing request
(venv) $ signing-tool -n approver.ini \
    imagesigning approve -I a83081a6-1d3b-4117-a81b-0ebcfcf0669c

# Get the signed payload
(venv) $ signing-tool -n test.ini \
    imagesigning get -I a83081a6-1d3b-4117-a81b-0ebcfcf0669c  --skipBase64  -O /tmp/response.tar.gz
```
