Skip to main content
Version: Next

3.4 Matrix Sample

3.4.1 Prepare

Matrix signature is a simple checksum algorithm, ICWKEY (PowerWriter) randomly generates a combination to encrypt the ID, and then write the encrypted information to the target chip during production, the target chip startup, the signature is verified, and is never used to verify that the current chip whether the signature information is written to the method of firmware protection, before starting, we need to follow the process to verify that all preparations have been completed. We need to follow the process to verify that all preparations have been completed.

  • ICWKEY signatures (or ICWKEY signature lock mode) are used in PowerWriter projects.
  • The signature address has been set (e.g. 0x08002000).
  • The communication information on the PowerWriter side has been synchronized to the project in ICWKEY and encrypted communication with the project has been re-established.
  • Reasonably set the number of times it can be authorized, for example, set it to 10,000.
  • Signature method: Matrix signature was chosen, saved to ICWKEY, and the source code was exported.

The demo is shown below:

GIF 2024-4-24 10-46-42

If all the above steps are completed, you can see the display information of ICWKEY device and the exported source code information, refer to the following:

image-20240423150734312

At the same time the ICWKEY device will display the following message:

微信图片_20240423103742

3.4.2 Sample project

3.4.2.1 Prepare

Sample project path ICWKEY installation path, specifically:

C:\Users\用户名\AppData\Local\ICWKEY\Examples_for_mdk

ICWKEY desktop icon, you can quickly locate until, and copy the Matrix sample project to the specified path, and decompression, refer to the demo as follows:

GIF 2024-4-24 10-46-42

3.4.2.2 Code structure

3.4.2.2.1 cortex_chipid_binding.c

  • Replacing ICWKEY exported functions
//Replace it with the exported code from ICWKEY.
//The following code may warn in KEIL(MDK), ignore it
static void ChipUIDAlgo(char pUserID[], char pChipID[], char pKey[])
{
pKey[0] = pChipID[8] * pChipID[3] | pUserID[8] & pChipID[10] ;
pKey[1] = pChipID[5] + pChipID[2] - pChipID[7] ^ pChipID[11] ;
pKey[2] = pChipID[9] - pUserID[4] ^ pUserID[2] * pUserID[10] ;
pKey[3] = pChipID[1] | pUserID[0] & pUserID[11] + pUserID[7] ;
pKey[4] = pUserID[1] * pUserID[9] | pUserID[3] & pChipID[6] ;
pKey[5] = pUserID[6] - pChipID[4] + pChipID[0] ^ pUserID[5] ;
pKey[6] = pUserID[2] - pChipID[1] & pChipID[9] * pChipID[0] ;
pKey[7] = pUserID[11] | pUserID[4] ^ pChipID[11] + pUserID[5] ;
pKey[8] = pChipID[7] - pUserID[1] | pUserID[0] + pChipID[10] ;
pKey[9] = pUserID[3] * pUserID[10] & pChipID[4] ^ pChipID[6] ;
pKey[10] = pChipID[5] | pUserID[7] - pUserID[9] + pChipID[8] ;
pKey[11] = pUserID[8] ^ pUserID[6] * pChipID[3] & pChipID[2] ;
}

3.4.2.2.2 cortex_chipid_binding.h

  • Fill in the ID address (see the prompt ).
  • Change the signature address to the PowerWriter signature address.
  • Replace with UID_USERID_KEYx exported in ICWKEY .
  • Depending on the situation, whether placeholders are turned on or not.

/* Exported define --------------------------------------------------------*/

/* The following macros are automatically exported by the software supporting the burner.
Please do not modify them to keep them consistent */

#define UID_CHIP_MASK 0x5BD489F0 //Random generation
#define UID_CHIP_SIZE 12 //ChipID Size
/* ID address of the target chip, which can be queried according to the chip's manual */
#define UID_CHIP_ADDR (0x1FFFF7E8^UID_CHIP_MASK) //ChipID Inner Addr in chip

#define UID_KEY_LENGTH 12 //The password is the same length as the user ID input
//Signature information storage address, change to the address where the signature information is stored in the PowerWriter project 0x08002000
#define UID_KEYADDR_INNER (0x08002000^UID_CHIP_MASK) //Key Store Addr In flash

//Replace with the password exported in ICWKEY.
#define UID_USERID_LENGTH UID_KEY_LENGTH //Customize password length
#define UID_USERID_KEY1 0xAD683BDB //UserID 1
#define UID_USERID_KEY2 0xC973505C //UserID 2
#define UID_USERID_KEY3 0x72C3BC02 //UserID 3

#define UID_DATAENDIAN littleEndian //Data Endian


/*
Description:
This customisation is used to decide whether to placeholder (pre-allocate) the signature information in the firmware, to prevent overlapping with other function addresses, PowerWriter may accidentally erase the code when burning
PowerWriter may accidentally erase the code when burning and cause problems with the firmware, in this case, it is necessary to pre-allocate, so if the flag bit is 0, it means no placeholder, in this case, it is necessary to store the storage address of the signature information, stored outside the firmware.
Summary:
1: The signature address is within the actual firmware range, the placeholder must be turned on; The signature address is outside the actual firmware range, it is recommended not to open the placeholder to avoid the firmware is too large.
2:If the address exceeds 0.7 chip capacity, the placeholder is not turned on, and if the address is less than 0.7 chip capacity, the placeholder is turned on.
*/
#define UID_KEYADDR_PLACEHOLDER_EN 1 //Key Store Addr In Flash Enable/Disable Placeholder

tip

UID_CHIP_ADDR address, you can use PowerWriter to select the signature mode as Matrix, export the source code can see the actual ID address.

3.4.2.2.3 main.c

  • Initialization ID
  • Verify Signature
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//Used to print log messages from the serial port
int fputc(int ch, FILE *f)
{
uint8_t ch8 = (uint8_t)ch;
HAL_UART_Transmit(&huart2,&ch8,sizeof(ch8),5);
return (ch);
}
/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */


/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
MX_USART2_UART_Init(); // Serial port initialisation for log printing
/* USER CODE BEGIN 2 */
//Initial Chip
ChipUIDInitial(); //Signature initialisation, used to initialise chipid, for chips with non-consecutive IDs, please copy consecutively, please check code
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
//Check in your code
if(ChipUIDAlgo_Check()) //Verify the signature
{
//ok

printf("Ok:matrix verify passed!\r\n");
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
HAL_Delay(100);
}
else
{
//false
printf("Error:matrix verify failed!\r\n");
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
}

}
/* USER CODE END 3 */
}

tip

The sample code is just a demo, for more security, please note that hiding the code can improve the security, if necessary, contact us to get the MCU Common Security Protection Library to further enhance the firmware security and prevent the firmware from being reverse decompiled, cracked, and modified.

3.4.2.3 Compiling

Compiling the project will generate the test firmware in the directory Output\ TargetIC_Example.bin.

3.4.2.4 Validate

Reopen the PowerWriter project, add the TargetIC_Example.bin test firmware to the Program Memory page, and load the project into the PowerWriter device as shown below:

GIF 2024-4-24 10-53-18

Connect ICWKEY to PowerWriter, and connect the target PCB of MCU to be programmed, and connect the power supply for programming, the reference wiring is shown as follows.

image-20240423144333507

After programming, connect the serial port TX pin of the target PCB, you can see the output signature verification information, refer to the following:

GIF 2024-4-23 15-32-30

3.4.2.5 Debugging method

After using PowerWriter to sign the target firmware and program it to the target chip, you can check whether the signature is in effect by setting the status output. In complex scenarios, you can't determine the location of the problem simply by looking at the working status, and at this time, you need to debug the target chip, and the debugging steps are as follows:

  • Refer to the compilation and verification process to complete the programming
  • IDE selection: No erasing target chip, no programming target chip, no calibrating target chip is performed.

The reference demo is shown below:

GIF 2024-4-23 14-48-39