MCUXpresso_LPC55S69/boards/lpcxpresso55s69/driver_examples/puf/cm33_core0/puf.c
2022-08-23 23:05:58 +08:00

178 lines
5.7 KiB
C

/*
* Copyright 2018-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include <stdlib.h>
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_puf.h"
#include "fsl_power.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define CORE_CLK_FREQ CLOCK_GetFreq(kCLOCK_CoreSysClk)
/* Worst-case time in ms to fully discharge PUF SRAM */
#define PUF_DISCHARGE_TIME 400
#define PUF_INTRINSIC_KEY_SIZE 16
/*******************************************************************************
* Variables
******************************************************************************/
/* User key in little-endian format. */
/* 32 bytes key for ECB method: "Thispasswordisveryuncommonforher". */
static const uint8_t s_userKey256[] __attribute__((aligned)) = {
0x72, 0x65, 0x68, 0x72, 0x6f, 0x66, 0x6e, 0x6f, 0x6d, 0x6d, 0x6f, 0x63, 0x6e, 0x75, 0x79, 0x72,
0x65, 0x76, 0x73, 0x69, 0x64, 0x72, 0x6f, 0x77, 0x73, 0x73, 0x61, 0x70, 0x73, 0x69, 0x68, 0x54};
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function.
*/
int main(void)
{
status_t result;
uint8_t activationCode[PUF_ACTIVATION_CODE_SIZE];
uint8_t keyCode0[PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(32)];
uint8_t keyCode1[PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(PUF_INTRINSIC_KEY_SIZE)];
uint8_t intrinsicKey[PUF_INTRINSIC_KEY_SIZE] = {0};
/* Init hardware */
/* set BOD VBAT level to 1.65V */
POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
/* attach main clock divide to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
/* Initialize random number generator used to generate key mask for HW key */
/* In real application, the seed shall be obtained from a hardware random number generator. */
srand(0xbabadeda);
PRINTF("PUF Peripheral Driver Example\r\n\r\n");
/* PUF SRAM Configuration*/
puf_config_t conf;
PUF_GetDefaultConfig(&conf);
/* Initialize PUF peripheral */
result = PUF_Init(PUF, &conf);
if (result != kStatus_Success)
{
PRINTF("Error Initializing PUF!\r\n");
goto cleanup;
}
/* Perform enroll to get device specific PUF activation code */
/* Note: Enroll operation is usually performed only once for each device. */
/* Activation code is stored and used in Start operation */
result = PUF_Enroll(PUF, activationCode, sizeof(activationCode));
if (result == kStatus_EnrollNotAllowed)
{
PRINTF("Enroll is not allowed!\r\n");
PRINTF("Will make powercycle and enroll again!\r\n");
(void)PUF_PowerCycle(PUF, &conf);
result = PUF_Enroll(PUF, activationCode, sizeof(activationCode));
}
if (result != kStatus_Success)
{
PRINTF("Error during Enroll!\r\n");
goto cleanup;
}
PUF_Deinit(PUF, &conf);
/* Reinitialize PUF after enroll */
result = PUF_Init(PUF, &conf);
if (result != kStatus_Success)
{
PRINTF("Error Initializing PUF!\r\n");
goto cleanup;
}
/* Start PUF by loading generated activation code */
result = PUF_Start(PUF, activationCode, sizeof(activationCode));
if (result == kStatus_StartNotAllowed)
{
PRINTF("Start is not allowed!\r\n");
PRINTF("Will make powercycle and start again!\r\n");
(void)PUF_PowerCycle(PUF, &conf);
result = PUF_Start(PUF, activationCode, sizeof(activationCode));
}
if (result != kStatus_Success)
{
PRINTF("Error during Start !\r\n");
goto cleanup;
}
/* Create keycode for user key with index 0 */
/* Index 0 selects that the key shall be ouptut (by PUF_GetHwKey()) to a SoC specific private hardware bus. */
result = PUF_SetUserKey(PUF, kPUF_KeyIndex_00, s_userKey256, 32, keyCode0, sizeof(keyCode0));
if (result != kStatus_Success)
{
PRINTF("Error setting user key!\r\n");
goto cleanup;
}
/* Generate new intrinsic key with index 1 */
result = PUF_SetIntrinsicKey(PUF, kPUF_KeyIndex_01, PUF_INTRINSIC_KEY_SIZE, keyCode1, sizeof(keyCode1));
if (result != kStatus_Success)
{
PRINTF("Error setting intrinsic key!\r\n");
goto cleanup;
}
/* Reconstruct key from keyCode0 to HW bus for crypto module */
result = PUF_GetHwKey(PUF, keyCode0, sizeof(keyCode0), kPUF_KeySlot0, rand());
if (result != kStatus_Success)
{
PRINTF("Error reconstructing key to HW bus!\r\n");
goto cleanup;
}
/* Reconstruct intrinsic key from keyCode1 generated by PUF_SetIntrinsicKey() */
result = PUF_GetKey(PUF, keyCode1, sizeof(keyCode1), intrinsicKey, sizeof(intrinsicKey));
if (result != kStatus_Success)
{
PRINTF("Error reconstructing intrinsic key!\r\n");
goto cleanup;
}
PRINTF("Reconstructed intrinsic key = ");
for (int i = 0; i < PUF_INTRINSIC_KEY_SIZE; i++)
{
PRINTF("%x ", intrinsicKey[i]);
}
cleanup:
PUF_Deinit(PUF, &conf);
PRINTF("\r\n\nExample end.\r\n");
while (1)
{
}
}