xilskey
Vitis Drivers API Documentation
xilskey_efuse_example.c File Reference

Overview

xilskey_efuse_example.c

Note
            Contains the api functions for the PS & PL eFUSE functionality.
            eFUSE Application project is capable of programming the PS and PL eFUSE
            bits given by the user. PS eFUSE holds the RSA primary key hash bits and
            user feature bits, which will enable/disable some features in ZYNQ.
            In Zynq PL eFUSE holds the AES key, user key and some feature bits and
    and in Ultrascale eFUSE holds AES key, User key, RSA key Hash and
    some feature bits.
            User has the provision to write PS eFUSE & PL eFUSE independently or
            can combine together. This can be selected by using the compilation
            switch provided in xilskey_input.h. XSK_EFUSEPS_DRIVER should be
            defined to enable PS functionality & XSK_EFUSEPL_DRIVER for PL
            functionality.
    However for programming eFuse Ultrascale only XSK_EFUSEPL_DRIVER should be
    enabled.

    eFUSE bits are one-time programmable. Once they are burnt, they
    cannot be changed. Make sure you enter the correct information before
    you program eFUSE bits.

    POR reset is required for the eFUSE values to become into effect.
    Please do a POR reset after eFUSE writing.

            All the user configurable parameters for PS & PL eFUSE writing should be
            defined in xilskey_input.h. By default, all the macros will be defined
            with FALSE values.

    For Zynq
    -----------------------------------------------------------------------
            For PL eFUSE writing enabling the caches are necessary if the image is
            executing from DDR. This will be done in  BSP by default. User has to
            take care not to disable caches.

    eFUSE writing procedure running out of DDR as an application:
    (This sequence is same as the existing flow described below)

    1)      After providing the required inputs in xilskey_input.h, compile the
            project.
    2)      Take the latest FSBL (.elf) and stitch the <output>.elf generated
            to it using the bootgen utility and generate a bootable image.
    3)      Write the generated binary image into the flash device.
            (Ex: QSPI,NAND etc)
    4)      Execute image from flash which will write the mentioned eFUSE key
            bits.

            eFUSE driver compilation procedure for OCM:

    1)      Open the linker script (lscript.ld) in the SDK project.
    2)      Now map all the sections points to “ps7_ram_0_S_AXI_BASEADDR”
                instead of “ps7_ddr_0_S_AXI_BASEADDR”.

    Example:        Click on the “Memory Region” tab for .text section & select
                            “ps7_ram_0_S_AXI_BASEADDR” from the drop down list.

    3)      Copy the ps7_init.c & ps7_init.h files from the hw_platform folder
            into the example folder.
    4)      Uncomment calling of “ps7_init()” routine in
            “xilskey_efuse_example.c”
    5)      Compile the project.
    6)      <project name>.elf  will be generated. This will be executed
            out of OCM.


    For Ultrascale
    -----------------------------------------------------------------------
    Accessing Ultrascale microblaze 's eFuse is done by using block RAM
    initialization.
    Ultrascale eFUSE programming is done through MASTER JTAG. Crucial
    Programming sequence will be taken care by Hardware module. So Hardware
    module should be added compulsory in the design. Please use hardware
    module's vhd code and instructions provided to add Hardware module
    in the design.

    Software will handover jtag navigation to Hardware module before
    entering JTAG IDLE state, by setting START pin of Hardware module to
    high and once programming of specified bit is done Hardware module
    will set END pin to high.

    Master Jtag primitive has to added to design i.e MASTER_JTAG_inst
    instantiation have to performed and AXI GPIO pins has to be connected
    to TDO, TDI, TMS and TCK signals of MASTER_JTAG primitive.

    Hardware module has to be added to our design and respective pins of
    the hardware module needs to be connected to AXI GPIO pins.
    Hardware module has three signals READY, START and END.

    All Inputs(TDO, READY and END) and All Outputs(TDI, TMS, TCK, START) of
    Hardware module, MASTER_JTAG can be connected as follows.
    1) All Inputs to one channel
            All Outputs to other channel
    Valid example: All Outputs connected to Channel 1
            Input signal TDO also connected to channel 2
    2) All Inputs and All Outputs to same channel.
    Valid example: All Outputs connected to Channel 1
                    Input signal TDO also connected to channel 1
    3) But some of the Outputs in one channel and some of them in different
    channel is not accepted.
    Invalid example: All Outputs connected to Channel 1
            Input signals (TDI, TMS) connected to Channel 1
            Input signal TCK also connected to channel 2
    The design should only contain AXI bram Ctrl memory mapped(1MB).
    System management wizard should be operated in DRP interface.
    Note: MASTER_JTAG will disable all other JTAGs

    Procedure to access efuse of Ultrascale:
    1) After providing the required inputs in xilskey_input.h, compile the
    project.
    2) Generate a memory mapped interface(mmi) file using TCL command
    write_mem_info $Outfilename
    3) Create an associate elf file.
                    (OR)
    Update memory has to be done using the tcl command updatemem.
    updatemem -meminfo $file.mmi -data $Outfilename.elf -bit $design.bit
                            -proc design_1_i/microblaze_0 -out $Final.bit
    4) Program the board using $Final.bit bitstream
    5) Output can be seen in UART terminal.
    6) For calculating CRC of AES key reverse polynomial is 0x82F63B78 or
    one can use the API u32 XilSKey_CrcCalculation(u8 *Key)

MODIFICATION HISTORY:

Ver Who Date Changes


1.00a rpoolla 04/26/13 First release 1.02a hk 10/28/13 Added use of API's read status and key. PR# 735957. 3.00 vns 31/07/15 Modified XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE macro name to XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE. Added missing goto statement. Modified init function, intialisation of instance is done based on the platform and Modified example to support both Zynq PL's eFuse and also Ultrascale's eFuse. 4.00 vns 09/10/15 Added DFT JTAG disable and DFT MODE disable programming and reading options for Zynq eFuse PS. 6.0 vns 07/07/16 Added Gpio pin numbers connected to hardware module. 6.4 vns 02/27/18 Added support for programming secure bit 6 - enable obfuscation feature for eFUSE AES key 03/09/17 Corrected status bits of Ultrascale plus 6.7 arc 10/29/18 Fixed ARMCC compiler warnings and errors psl 03/20/19 Added eFuse key write support for SSIT devices. psl 03/29/19 Added support for user configurable GPIO for jtag control. psl 04/29/19 Resolved GCC warnings. 6.8 psl 05/21/19 Added platform dependent macros for variables and initialized PlStatus. Added print for current SLR and CRC. 07/17/19 Added print to display CRC of AES key during CRC verification. 08/30/19 Corrected length in bits parameter while converting PPK hash string(zynq efuse ps) 7.6 vns 04/04/24 Updated efuse PL secure bits of ultrascale devices

Macros

#define REBOOT_STATUS_REG_ADDR   (0xF8000258)
 Address for the Reboot Status Register. More...
 
#define XSK_EFUSEPL_USER_KEY_SIZE_IN_BITS   (32)
 user key size in bits More...
 
#define XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE   (96)
 PL eFUSE RSA key size in characters. More...
 
#define XSK_EFUSEPL_RSA_KEY_SIZE_IN_BITS   (384)
 RSA Key size in Bytes. More...
 
#define XSK_EFUSEPL_USER_KEY_STRING_SIZE   (8)
 PL eFuse user key size in characters. More...
 

Functions

u32 XilSKey_Efuse_ConvertStringToHexLE (const char *Str, u8 *Buf, u32 Len)
 Function used to convert the string to Hex in Little Endian format. More...
 
u32 XilSKey_Efuse_ConvertStringToHexBE (const char *Str, u8 *Buf, u32 Len)
 Function used to convert the string to Hex in Little Endian format. More...
 
u32 XilSKey_Efuse_ValidateKey (const char *Key, u32 Len)
 Function used to validate the AES & RSA key provided as input. More...
 
u32 XilSKey_EfusePs_InitData (XilSKey_EPs *PsInstancePtr)
 Helper functions to properly initialize the PS eFUSE structure instance. More...
 
u32 XilSKey_EfusePl_InitData (XilSKey_EPl *PlInstancePtr)
 Helper functions to validate the keys to be written. More...
 
u32 XilSKey_EfusePl_ReadnCheck (XilSKey_EPl *PlInstancePtr)
 Wrapper functions to program and read keys. More...
 
int main ()
 

Macro Definition Documentation

#define REBOOT_STATUS_REG_ADDR   (0xF8000258)

Address for the Reboot Status Register.

Referenced by main().

#define XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE   (96)

PL eFUSE RSA key size in characters.

#define XSK_EFUSEPL_RSA_KEY_SIZE_IN_BITS   (384)

RSA Key size in Bytes.

#define XSK_EFUSEPL_USER_KEY_SIZE_IN_BITS   (32)

user key size in bits

#define XSK_EFUSEPL_USER_KEY_STRING_SIZE   (8)

PL eFuse user key size in characters.

Function Documentation

int main ( )

Initialize the PS instance pointer with the data populated in xilskey_input.h

Write the PS eFUSE as defined in xilskeyinput.h

Clear the structure element of Rsa Key Hash for reading

Read the PS eFUSE RSA Key Hash

Print the read PS eFUSE RSA Key Hash

Initialize the PL data structure based on the xilskey_input.h values

Verify the SLR requested to program against target validity

Program and Read for SLRX Programming will not happen until corresponding PGM_SLR1 is not TRUE

References XilSKey_EPl::NumSlr, REBOOT_STATUS_REG_ADDR, XilSKey_EPl::SlrConfigOrderIndex, XilSKey_EfusePl_InitData(), XilSKey_EfusePl_Program(), XilSKey_EfusePl_ReadnCheck(), XilSKey_EfusePl_SystemInit(), XilSKey_EfusePs_InitData(), XilSKey_EfusePs_Read(), XilSKey_EfusePs_ReadStatus(), and XilSKey_EfusePs_Write().

u32 XilSKey_Efuse_ConvertStringToHexBE ( const char *  Str,
u8 *  Buf,
u32  Len 
)

Function used to convert the string to Hex in Little Endian format.

Function used to convert the string to Hex in Little Endian format.

 Ex: "abc123" -> {0xab, 0xc1, 0x23}
Parameters
Stris a Input String. Will support the lower and upper case values. Value should be between 0-9, a-f and A-F
Bufis Output buffer.
Lenof the input string in bits and it should have even values
Returns
  • XST_SUCCESS no errors occurred.
  • XST_FAILURE an error when input parameters are not valid
  • an error when input buffer has invalid values

TDD Test Cases: —Initialization— Len is odd Len is zero Str is NULL Buf is NULL —Functionality— Str input with only numbers Str input with All values in A-F Str input with All values in a-f Str input with values in a-f, 0-9, A-F Str input with values in a-z, 0-9, A-Z Boundary Cases Memory Bounds of buffer checking

Check the parameters

Len has to be multiple of 2

Convert char to nibble

Convert char to nibble

Merge upper and lower nibble to Hex

Error converting Lower nibble

Error converting Upper nibble

Converted upper and lower nibbles

References XSK_EFUSEPS_ERROR_INVALID_PARAM, XSK_EFUSEPS_ERROR_PARAMETER_NULL, and XSK_EFUSEPS_ERROR_STRING_INVALID.

Referenced by XilSKey_Bbram_InitData(), XilSKey_CrcCalculation(), and XilSKey_EfusePs_InitData().

u32 XilSKey_Efuse_ConvertStringToHexLE ( const char *  Str,
u8 *  Buf,
u32  Len 
)

Function used to convert the string to Hex in Little Endian format.

Function used to convert the string to Hex in Little Endian format.

 Ex: "abc123" -> {0x23, 0xc1, 0xab}
Parameters
Stris a Input String. Will support the lower and upper case values. Value should be between 0-9, a-f and A-F
Bufis Output buffer.
Lenof the input string in bits and it should have even values
Returns
  • XST_SUCCESS no errors occurred.
  • XST_FAILURE an error when input parameters are not valid
  • an error when input buffer has invalid values

TDD Test Cases: —Initialization— Len is odd Len is zero Str is NULL Buf is NULL —Functionality— Str input with only numbers Str input with All values in A-F Str input with All values in a-f Str input with values in a-f, 0-9, A-F Str input with values in a-z, 0-9, A-Z Boundary Cases Memory Bounds of buffer checking

Check the parameters

Len has to be multiple of 2

Convert char to nibble

Convert char to nibble

Merge upper and lower nibble to Hex

Error converting Lower nibble

Error converting Upper nibble

Converted upper and lower nibbles

References XSK_EFUSEPS_ERROR_INVALID_PARAM, XSK_EFUSEPS_ERROR_PARAMETER_NULL, and XSK_EFUSEPS_ERROR_STRING_INVALID.

Referenced by main(), and XilSKey_EfusePl_InitData().

u32 XilSKey_Efuse_ValidateKey ( const char *  Key,
u32  Len 
)

Function used to validate the AES & RSA key provided as input.

Function used to validate the AES & RSA key provided as input.

Parameters
Key- Hash Key
Len- Valid length of key
Returns
XST_SUCCESS - In case of Success XST_FAILURE - In case of Failure

Make sure the key has valid length

Make sure the key has valid characters

References XilSKey_Efuse_IsValidChar(), XSK_EFUSEPL_ERROR_KEY_VALIDATION, XSK_EFUSEPL_ERROR_NONE, XSK_EFUSEPL_ERROR_NOT_VALID_KEY_CHAR, and XSK_EFUSEPL_ERROR_NOT_VALID_KEY_LENGTH.

Referenced by XilSKey_EfusePl_InitData(), and XilSKey_EfusePs_InitData().

u32 XilSKey_EfusePl_InitData ( XilSKey_EPl PlInstancePtr)

Helper functions to validate the keys to be written.

Parameters
PlInstancePtr- Structure Address to update the structure elements
SlrNum- Number to differentiate the data targeted to specific SLR
Returns
  - XST_SUCCESS - In case of Success
  - Error - If initialization fails
Note

Helper functions to properly initialize the PL eFUSE structure instance

Parameters
PlInstancePtr- Structure Address to update the structure elements
Returns
  - XST_SUCCESS - In case of Success
  - XST_FAILURE - If initialization fails
Note

Copy the xilskeyinput.h values into PL eFUSE structure elements

Assign FUSE CNTRL bits[1:5] to the PL eFUSE structure elements.

References XilSKey_EPl::AESKey, XilSKey_EPl::AESKeyExclusive, XilSKey_EPl::AESKeyRead, XilSKey_EPl::CheckAESKeyUltra, XilSKey_EPl::CtrlWrite, XilSKey_EPl::DecoderDisable, XilSKey_EPl::EncryptOnly, XilSKey_EPl::ForcePowerCycle, XilSKey_EPl::FuseObfusEn, XilSKey_EPl::GpioInputCh, XilSKey_EPl::GpioOutPutCh, XilSKey_EPl::HwmGpioEnd, XilSKey_EPl::HwmGpioReady, XilSKey_EPl::HwmGpioStart, XilSKey_EPl::IntTestAccessDisable, XilSKey_EPl::JtagDisable, XilSKey_EPl::JtagGpioID, XilSKey_EPl::JtagGpioTCK, XilSKey_EPl::JtagGpioTDI, XilSKey_EPl::JtagGpioTDO, XilSKey_EPl::JtagGpioTMS, XilSKey_EPl::JtagMioMuxSel, XilSKey_EPl::JtagMioTCK, XilSKey_EPl::JtagMioTDI, XilSKey_EPl::JtagMioTDO, XilSKey_EPl::JtagMioTMS, XilSKey_EPl::JtagMuxSelLineDefVal, XilSKey_EPl::KeyWrite, XilSKey_EPl::ProgAESandUserLowKey, XilSKey_EPl::ProgAESKeyUltra, XilSKey_EPl::ProgRSAKeyUltra, XilSKey_EPl::ProgUser128BitUltra, XilSKey_EPl::ProgUserHighKey, XilSKey_EPl::ProgUserKeyUltra, XilSKey_EPl::ReadRSAKeyUltra, XilSKey_EPl::ReadUser128BitUltra, XilSKey_EPl::ReadUserKeyUltra, XilSKey_EPl::RSAEnable, XilSKey_EPl::RSARead, XilSKey_EPl::RSAWrite, XilSKey_EPl::SecureRead, XilSKey_EPl::SecureWrite, XilSKey_EPl::SystemInitDone, XilSKey_EPl::UseAESOnly, XilSKey_EPl::User128BitWrite, XilSKey_EPl::UserKey, XilSKey_EPl::UserKeyRead, XilSKey_EPl::UserKeyWrite, XilSKey_Efuse_ConvertStringToHexLE(), XilSKey_Efuse_ValidateKey(), XSK_EFUSEPL_ALLOW_ENCRYPTED_ONLY, XSK_EFUSEPL_AXI_GPIO_DEVICE_ID, XSK_EFUSEPL_AXI_GPIO_HWM_END, XSK_EFUSEPL_AXI_GPIO_HWM_READY, XSK_EFUSEPL_AXI_GPIO_HWM_START, XSK_EFUSEPL_AXI_GPIO_JTAG_TCK, XSK_EFUSEPL_AXI_GPIO_JTAG_TDI, XSK_EFUSEPL_AXI_GPIO_JTAG_TDO, XSK_EFUSEPL_AXI_GPIO_JTAG_TMS, XSK_EFUSEPL_CHECK_AES_KEY_CRC, XSK_EFUSEPL_DISABLE_128BIT_USER_KEY_WRITE, XSK_EFUSEPL_DISABLE_AES_DECRYPTOR, XSK_EFUSEPL_DISABLE_AES_KEY_READ, XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE, XSK_EFUSEPL_DISABLE_JTAG_CHAIN, XSK_EFUSEPL_DISABLE_KEY_WRITE, XSK_EFUSEPL_DISABLE_RSA_HASH_WRITE, XSK_EFUSEPL_DISABLE_RSA_KEY_READ, XSK_EFUSEPL_DISABLE_SECURE_READ, XSK_EFUSEPL_DISABLE_SECURE_WRITE, XSK_EFUSEPL_DISABLE_TEST_ACCESS, XSK_EFUSEPL_DISABLE_USER_KEY_READ, XSK_EFUSEPL_DISABLE_USER_KEY_WRITE, XSK_EFUSEPL_ENABLE_OBFUSCATION_EFUSEAES, XSK_EFUSEPL_ENABLE_RSA_AUTH, XSK_EFUSEPL_FORCE_USE_FUSE_AES_ONLY, XSK_EFUSEPL_GPIO_INPUT_CH, XSK_EFUSEPL_GPIO_OUTPUT_CH, XSK_EFUSEPL_PROGRAM_AES_KEY, XSK_EFUSEPL_PROGRAM_RSA_KEY_HASH, XSK_EFUSEPL_PROGRAM_USER_KEY, XSK_EFUSEPL_PROGRAM_USER_KEY_128BIT, XSK_EFUSEPL_READ_RSA_KEY_HASH, XSK_EFUSEPL_READ_USER_KEY, and XSK_EFUSEPL_READ_USER_KEY128_BIT.

Referenced by main().

u32 XilSKey_EfusePl_ReadnCheck ( XilSKey_EPl PlInstancePtr)

Wrapper functions to program and read keys.

Parameters
PlInstancePtr- Structure Address to update the structure elements
SlrNum- Number to differentiate the data targeted to specific SLR
Returns
  - XST_SUCCESS - In case of Success
  - Error - If initialization fails
Note

Helper functions to validate the keys to be written

Parameters
PlInstancePtr- Structure Address to update the structure elements
SlrNum- Number to differentiate the data targeted to specific SLR
Returns
  - XST_SUCCESS - In case of Success
  - Error - If initialization fails
Note

References XilSKey_EPl::AESKeyMatched, XilSKey_EPl::AESKeyReadback, XilSKey_EPl::CrcOfAESKey, XilSKey_EPl::FpgaFlag, XilSKey_EPl::RSAHashReadback, XilSKey_EPl::User128BitReadBack, XilSKey_EPl::UserKeyReadback, XilSKey_EfusePl_ReadKey(), XilSKey_EfusePl_ReadStatus(), XSK_EFUSEPL_CHECK_AES_KEY_CRC, XSK_EFUSEPL_READ_RSA_KEY_HASH, XSK_EFUSEPL_READ_USER_KEY, and XSK_EFUSEPL_READ_USER_KEY128_BIT.

Referenced by main().

u32 XilSKey_EfusePs_InitData ( XilSKey_EPs *  PsInstancePtr)

Helper functions to properly initialize the PS eFUSE structure instance.

Parameters
PsInstancePtr- Structure Address to update the structure elements
Returns
  - XST_SUCCESS - In case of Success
  - XST_FAILURE - If initialization fails
Note

Copy the xilskeyinput.h values into PS structure elements

Validation of RSA Hash

Convert the input RSA Key Hash string into Hex buffer

References XilSKey_Efuse_ConvertStringToHexBE(), XilSKey_Efuse_ValidateKey(), XSK_EFUSEPS_DISABLE_DFT_JTAG, XSK_EFUSEPS_DISABLE_DFT_MODE, XSK_EFUSEPS_ENABLE_ROM_128K_CRC, XSK_EFUSEPS_ENABLE_RSA_AUTH, XSK_EFUSEPS_ENABLE_RSA_KEY_HASH, and XSK_EFUSEPS_ENABLE_WRITE_PROTECT.

Referenced by main().