# Table of Contents
- [Quick Start](#quick-start)
- [Secure Certificates](#secure-certificates)
  - [Key Certificate](#key-certificate)
  - [Content Certificate](#content-certificate)
  - [Generate Secure Certificates](#generate-secure-certificates)
- [Secure Image](#secure-image)
- [Encrypt Application](#encrypt-application)
- [OTA Image](#ota-image)
- [Erase Device Flash Memory](#erase-device-flash-memory)
- [Read Device CSR](#read-device-csr)
- [Read Device SOC ID](#read-device-soc-id)
- [Device Provisioning](#device-provisioning)

# Quick Start
## 1. Create ModusToolbox Application
Create `HAL_Blinky_LED` project in ModusToolbox™ using CYW955913EVK-01 BSP.
Build the project for external memory.

There are two files in the build directory needed to sign and/or encrypt the application:
 - mtb-example-threadx-blinky-led_ds_sub.tbl
 - mtb-example-threadx-blinky-led_download.hex

## 2. Create Project
```bash
$ edgeprotecttools -t cyw559xx init
```

## 3. Create Keys
Create three RSA key pairs of the 3072-bit size to sign the certificate chain. Optionally, create an AES-128 key to encrypt the application.
```bash
# Create first key pair, also used for provisioning
$ edgeprotecttools create-key --key-type RSA3072 --output keys/first_privkey.pem keys/first_pubkey.pem
 
# Create a second key pair
$ edgeprotecttools create-key --key-type RSA3072 --output keys/second_privkey.pem keys/second_pubkey.pem
 
# Create content key pair
$ edgeprotecttools create-key --key-type RSA3072 --output keys/content_privkey.pem keys/content_pubkey.pem
 
# Create encryption key if application has to be encrypted
$ edgeprotecttools create-key --key-type AES128 --output keys/enckey.bin
```

## 4. Create First Key Certificate
Fill the key certificate configuration file for the first key (`certs/key_cert_config.json`).
```json
{
  "certificate": {
    "type": "KEY_CERT",
    "version": 1.0
  },
  "cert_keypair": {
    "description": "Path to the private key used to sign the certificate. The RSA key of the 3072-bit size",
    "value": "../keys/first_privkey.pem"
  },
  "cert_keypair_pwd": {
    "description": "Certificate private key password (if applicable)",
    "value": ""
  },
  "nv_counter": {
    "description": "Non-Volatile counter corresponding to the software version in the certificate",
    "value": 0
  },
  "next_cert_pubkey": {
    "description": "Path to the public key of the next certificate in the chain. The RSA key of the 3072-bit size",
    "value": "../keys/second_pubkey.pem"
  }
}
```
Generate the certificate.
```bash
# Generate first key certificate
$ edgeprotecttools -t cyw559xx secure-cert --config certs/key_cert_config.json --output certs/first_cert.cer
```

## 5. Create Second Key Certificate
Fill the key certificate configuration file for the second key (`certs/key_cert_config.json`).
```json
{
  "certificate": {
    "type": "KEY_CERT",
    "version": 1.0
  },
  "cert_keypair": {
    "description": "Path to the private key used to sign the certificate. The RSA key of the 3072-bit size",
    "value": "../keys/second_privkey.pem"
  },
  "cert_keypair_pwd": {
    "description": "Certificate private key password (if applicable)",
    "value": ""
  },
  "nv_counter": {
    "description": "Non-Volatile counter corresponding to the software version in the certificate",
    "value": 0
  },
  "next_cert_pubkey": {
    "description": "Path to the public key of the next certificate in the chain. The RSA key of the 3072-bit size",
    "value": "../keys/content_pubkey.pem"
  }
}
```
Generate the certificate.
```bash
# Generate second key certificate
$ edgeprotecttools -t cyw559xx secure-cert --config certs/key_cert_config.json --output certs/second_cert.cer
```
## 6. Create Content Certificate
Fill the content certificate configuration file (`certs/content_cert_config.json`).
```json
{
  "certificate": {
    "type": "CONTENT_CERT",
    "version": 1.0
  },
  "cert_keypair": {
    "description": "Path to the private key used to sign the certificate. The RSA key of the 3072-bit size",
    "value": "../keys/content_privkey.pem"
  },
  "cert_keypair_pwd": {
    "description": "Certificate private key password (if applicable)",
    "value": ""
  },
  "nv_counter": {
    "description": "Non-Volatile counter corresponding to the software version in the certificate",
    "value": 0
  },
  "image_table": {
    "description": "A text file containing the list of SW image files to be processed (.tbl file generated by ModusToolbox™)",
    "value": "<path to the application .tbl file generated by ModusToolbox™ located at ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_ds_sub.tbl>"
  }
}
```
Generate the certificate.
```bash
# Generate content certificate
$ edgeprotecttools -t cyw559xx secure-cert --config certs/content_cert_config.json --output certs/content_cert.cer
```

## 7. Create Secure Image
This step signs the application by attaching the chain of certificates to the image.
```bash
# Sign the image by appending the certificates
$ edgeprotecttools -t cyw559xx secure-image --image ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download.hex --cert certs/first_cert.cer --cert certs/second_cert.cer --cert certs/content_cert.cer --output ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT.hex
```

## 8. Encrypt Application (optional)
If the application has to be encrypted, run the following command.
```bash
# Encrypt the application
$ edgeprotecttools -t cyw559xx encrypt --image ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT.hex --key keys/enckey.bin --iv 3f45a2c7b8e66d9f4a1b3c2e8d5f9a01 --output ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT_ENCRYPTED.hex
```

## 9. Generate HCD Image (optional)
Convert an IntelHex file to HCD (Hardware Configuration Data). HCD is a format used by Chipload. Latest Chipload versions support HEX files, so this step is optional.
```bash
$ edgeprotecttools hex2hcd --input ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT_ENCRYPTED.hex --output ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT_ENCRYPTED.hcd
```

## 10. Create OTA Image (optional)
The OTA image is a BIN file that is intended to be run by the OTA driver.
```bash
# Create an OTA image
$ edgeprotecttools -t cyw559xx ota-image --image ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_download_APPCERT_ENCRYPTED.hex --output ./HAL_Blinky_LED/build/APP_CYW955913EVK-01/Debug/mtb-example-threadx-blinky-led_APP_CYW955913EVK-01_APPCERT_ENCRYPTED.ota.bin
```

## 11. Provision Device
Provisioning and transferring the device to the SECURE LCS.
### Fill Provisioning Policy
#### For Unencrypted Application
```json
{
  "policy": {
    "platform": "cyw559xx",
    "version": 1.0,
    "type": "oem_provisioning"
  },
  "oem_public_key": {
    "description": "The path to the RSA public key of the 3072-bit size",
    "value": "../keys/first_pubkey.pem"
  },
  "provisioning_key": {
    "type": {
      "description": "Provisioning Key. Applicable values: ASSET_NO_KEY, ASSET_PLAIN_KEY",
      "value": "ASSET_NO_KEY"
    },
    "data": {
      "description": "Provisioning Key. Accepts hex string or path to binary file. If no key is provided, set the value to 'null'",
      "value": null
    }
  },
  "code_encryption_key": {
    "type": {
      "description": "Code Encryption Key. Applicable values: ASSET_NO_KEY, ASSET_PLAIN_KEY",
      "value": "ASSET_NO_KEY"
    },
    "data": {
      "description": "Code Encryption Key. Accepts hex string or path to binary file. If no key is provided, set the value to 'null'",
      "value": null
    }
  },
  "nv_counter": {
    "description": "Non-Volatile counter corresponding to the software version",
    "value": "0x00000000"
  }
}
```
#### For Encrypted Application
```json
{
  "policy": {
    "platform": "cyw559xx",
    "version": 1.0,
    "type": "oem_provisioning"
  },
  "oem_public_key": {
    "description": "The path to the RSA public key of the 3072-bit size",
    "value": "../keys/first_pubkey.pem"
  },
  "provisioning_key": {
    "type": {
      "description": "Provisioning Key. Applicable values: ASSET_NO_KEY, ASSET_PLAIN_KEY",
      "value": "ASSET_NO_KEY"
    },
    "data": {
      "description": "Provisioning Key. Accepts hex string or path to binary file. If no key is provided, set the value to 'null'",
      "value": null
    }
  },
  "code_encryption_key": {
    "type": {
      "description": "Code Encryption Key. Applicable values: ASSET_NO_KEY, ASSET_PLAIN_KEY",
      "value": "ASSET_PLAIN_KEY"
    },
    "data": {
      "description": "Code Encryption Key. Accepts hex string or path to binary file. If no key is provided, set the value to 'null'",
      "value": "../keys/enckey.bin"
    }
  },
  "nv_counter": {
    "description": "Non-Volatile counter corresponding to the software version",
    "value": "0x00000000"
  }
}
```
### Configure Serial Port
Provide the information about the protocol and the serial port.
```bash
# Configure serial port
$ edgeprotecttools serial-config --protocol uart --hwid <COM_PORT>
```
### Erase Flash Memory
Erases the device flash memory before provisioning.
```bash
# Erase the device flash memory
$ edgeprotecttools -t cyw559xx erase-flash
```
### Start Provisioning
__IMPORTANT__: Ensure that no application is running on the device before starting the provisioning process.
```bash
# Provision the device
$ edgeprotecttools -t cyw559xx provision-device --policy policy/policy_oem_provisioning.json
```

# Secure Certificates
Secure boot is based on certificate chain mechanisms using the RSA private and public key schemes.
The certificate structure consists of the following parts:
* Header, which includes information such as certificate type, version, size, owner, flags, and validity
period.
* Certificate data, including public key and application hash.
* Signature, which is calculated over the header and certificate data by using the RSA PSS scheme.

The link between a certificate and its next certificate is that the certificate includes the hash of the public key
of the next certificate.
There are two different types of certificates:
* Key certificate
* Content certificate

The certificate chain is composed of three self-signed certificates. Self-signed means that the public key 
is included in the certificate, and the certificate itself is signed with the corresponding private key. 
The chain consists of two key certificates and one content certificate.

## Key Certificate
The key certificate is used to validate the hash of the public key of the next certificate in the chain.
### Configuration File Parameters
| Property         | Description                                                                                            |
|------------------|--------------------------------------------------------------------------------------------------------|
| cert_keypair     | Path to the private key used to sign the certificate. It must be the RSA key of the 3072-bit size      |
| cert_keypair_pwd | Password for the certificate private key. Keep empty if the key is not encrypted by a password.        |
| nv_counter       | The Non-Volatile counter value. A value between 0 and 96.                                              |
| next_cert_pubkey | Path to the public key of the next certificate in the chain. Must be the RSA key of the 3072-bit size. |

## Content Certificate
The content certificate is used to load and validate software components.
### Configuration File Parameters
| Property           | Description                                                                                                                                                                                                                                                                                                                |
|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| cert_keypair       | Path to the private key used to sign the certificate. It must be the RSA key of the 3072-bit size.                                                                                                                                                                                                                         |
| cert_keypair_pwd   | Password for the certificate private key. Keep empty if the key is not encrypted by a password.                                                                                                                                                                                                                            |
| nv_counter         | The Non-Volatile counter value. A value between 0 and 96.                                                                                                                                                                                                                                                                  |
| load_verify_scheme | The scheme used to verify the software components. Applicable values: <br/>- RAM_LOAD_VERIFY - Load from flash to RAM and verify<br/>- FLASH_VERIFY - Full hash verification in flash without loading to RAM<br/>- RAM_VERIFY - Verify in RAM<br/>- RAM_LOAD - Load from flash into RAM                                    |
| encrypted          | Indicates whether the software components are encrypted.                                                                                                                                                                                                                                                                   |
| crypto_type        | Cryptographic verification and decryption mode. Applicable values:<br/>- PLAIN_IMAGE_HASH - Do hash on plain image<br/>- ENC_IMAGE_HASH - do hash on encrypted image                                                                                                                                                       |
| image_table        | Path to the `.tbl` file generated by ModusToolbox™. The file contains the list of authenticated SW images. The file is located in the project _build_ directory. Each line refers to a single image, with the following data: `<image_file_name> <mem_load addr> <flash_store_addr> <image_max_size> <is_encrypted_flag>`. |

## Generate Secure Certificates
Generates the key or content certificates.
### Command: `secure-cert`
### Parameters
| Name         | Optional/Required | Description                                                    |
|--------------|:-----------------:|----------------------------------------------------------------|
| -c, --config |     required      | The path to the key or content certificate configuration file. |
| -o, --output |     required      | The path to certificate output file.                           |
### Example
```bash
# Generate the key certificates
$ edgeprotecttools -t cyw559xx secure-cert --config certs/key_cert_config.json --output certs/first_key_cert.cer
$ edgeprotecttools -t cyw559xx secure-cert --config certs/key_cert_config.json --output certs/second_key_cert.cer

# Generate the content certificate
$ edgeprotecttools -t cyw559xx secure-cert --config certs/content_cert_config.json --output certs/content_cert.cer
```

# Secure Image
The secure image is a HEX file that contains the software components and the certificate chain.
The following command creates a secure image by merging key and content certificates into the application.
### Command: `secure-image`
### Parameters
| Name         | Optional/Required | Description                                                                                                                                                                                          |
|--------------|:-----------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| --image      |     required      | The path to the application HEX file.                                                                                                                                                                |
| --cert       |     required      | Certificate in DER format. Specify the option multiple times to add multiple certificates. Make sure the order is the following: first key certificate, second key certificate, content certificate. |
| -o, --output |     required      | The path where to save the output HEX file.                                                                                                                                                          |
| --hcd        |     optional      | The path where to save the hardware configuration data (HCD) file. HCD format is required by the Chipload tool to program the device.                                                                |
### Example
```bash
# Create a secure image. The order of the certificates must be the following: first key certificate, second key certificate, and content certificate.
$ edgeprotecttools -t cyw559xx secure-image --image mtb-example-threadx-hello-world_download.hex --cert certs/first_key_cert.cer --cert certs/second_key_cert.cer --cert certs/content_cert.cer --output mtb-example-threadx-hello-world_download_APPCERT.hex --hcd mtb-example-threadx-hello-world_download_APPCERT.hcd
```

# Encrypt Application
Encrypts the application.
### Command: `encrypt`
### Parameters
| Name              | Optional/Required | Description                                                  |
|-------------------|:-----------------:|--------------------------------------------------------------|
| -i, --image       |     required      | The path to the application HEX file.                        |
| --key, --key-path |     required      | The path to the AES-128 key used to encrypt the application. |
| --iv              |     required      | The initialization vector (16 bytes) used for encryption.    |
| -o, --output      |     required      | The encrypted image output path.                             |
### Example
```bash
# Encrypt application
$ edgeprotecttools -t cyw559xx encrypt --image mtb-example-threadx-hello-world_download_APPCERT.hex --key kce_app.bin --iv 0102030405060708090A0B0C --output mtb-example-threadx-hello-world_download_APPCERT_ENCRYPTED.hex
```

# OTA Image
The OTA image is a BIN file that is intended to be run by the OTA driver.
### Command: `ota-image`
### Parameters
| Name         | Optional/Required | Description                                                                                                                                                                                          |
|--------------|:-----------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| --image      |     required      | The path to the application HEX file.                                                                                                                                                                |
| -o, --output |     required      | The path where to save the output BIN file.                                                                                                                                                          |
### Example
```bash
# Create an OTA image
$ edgeprotecttools -t cyw559xx ota-image --image mtb-example-threadx-hello-world_download_APPCERT.hex --output mtb-example-threadx-empty-app_APP_CYW955913EVK-01_APPCERT.ota.bin
```

# Erase Device Flash Memory
Erases the device flash memory.
### Command: `erase-flash`
### Example
```bash
# Erase the device flash memory
$ edgeprotecttools -t cyw559xx erase-flash
```

# Read Device CSR
Reads the device CSR from CYW559xx.
### Command: `get-csr`
### Parameters
| Name         | Optional/Required | Description                                                                     |
|--------------|:-----------------:|---------------------------------------------------------------------------------|
| -o, --output |     required      | The path where to save the output CSR file. The output file is in DER encoding. |
| --csr-id     |     optional      | The CSR ID. The default value is 0.                                             |
### Example
```bash
# Read the device CSR from CYW559xx
$ edgeprotecttools -t cyw559xx get-csr --output csr.der
```

# Read Device SOC ID
Reads the device SOC ID from CYW559xx.

__IMPORTANT__: Ensure that no application is running on the device. Run [erase-flash](#erase-device-flash-memory) before this command.
### Command: `read-soc-id`
### Parameters
| Name         | Optional/Required | Description                                                                     |
|--------------|:-----------------:|---------------------------------------------------------------------------------|
| -o, --output |     optional      | The path where to save the result.                                              |
### Example
```bash
# Read the device SOC ID from CYW559xx
$ edgeprotecttools -t cyw559xx read-soc-id
```

# Device Provisioning
The provisioning process configures the device according to the specified policy file, which includes the Root of Trust (RoT) and encryption keys to ensure secure operation.

The policy JSON file can typically be found in the `policy` directory of the project. Ensure that the file is properly configured before running the provisioning command.

__IMPORTANT__: Ensure that no application is running on the device. Run [erase-flash](#erase-device-flash-memory) before this command.
### Command: `provision-device`
### Parameters
| Name              | Optional/Required | Description                                                 |
|-------------------|:-----------------:|-------------------------------------------------------------|
| -p, --policy      |     required      | The path to the policy file.                                |
| --existing-packet |     optional      | Skip provisioning packet creation and use the existing one. |
### Example
```bash
# Provision the device
$ edgeprotecttools -t cyw559xx provision-device --policy policy/policy_oem_provisioning.json
```
