S12Z Firmware Security

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S12Z Firmware Security

2,213 Views
manishsangram
Contributor IV

Hello,

We are using the S12ZVMC128 and we need maximum protection for firmware. We are aware of the FSEC Firmware Security bits, but as we know there are a lot of hackers who can somehow reset bits etc.

We are NOT using any boot loader, so we only expect to program via the MCU programming interface which will be available on our custom board.

We do not want anyone to read the FLASh or EEPROM or SRAM, so the best we can do as per the Reference Manual is to set the Flash Security States bits to 00. Is this enough in the real world?

How secure is the S12Z series against most hacking approaches both hardware and software? Is there any documentation on the same?

Is there any unique ID coded in each chip which we can access ?  At least this could help us locking the firmware to a specific physical chip.

Any help would be highly appreciated.

Manish

12 Replies

1,210 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

the link you are mention is not a link even it looks like a link. Mea culpa, I have only copy/paste it. It is a path where the table is stored in the CodeWarrior help structure. The same you can see under my signature where I copy/past the page from the help.

The same you can find if you write, for example, "DW" into the search and it direct you to a debugger Shell Commands.

Probably answer on the second part is  already answered: https://community.nxp.com/thread/455729 

If you want fre tool then it is enough to install special edition version of the CodeWarrior which has some limitations for compiler.

Best regrads,

Ladislav

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

The sources of information are:

- CodeWarrior for Microcontrollers V10.x > Targeting Microcontrollers > Microcontrollers V10.x Targeting Manual > CodeWarrior Command Line Debugging > Microcontrollers-Specific HIWARE Commands

(se list bellow)

- Tcl Reference Manual 

- http://www.tcl.tk/ 

The device id is size of 8 bytes from 1F_C000 to 1F_C007. Of course you can read also other "reserved" field but they store  data the meaning is confidential, so I am sorry, I am not allowed to share. The same is valid for meaning of the device ID fields.

Best regards,

Ladislav

Command List

The table below lists the supported HIWARE commands followed by:

  • CodeWarrior debugger shell syntax,
  • partially supported commands,
  • commands that are not applicable in CodeWarrior
  • commands supported in script files with Tcl control flow statements, and
  • unsupported commands.

The following columns represent the status in the CodeWarrior Eclipse IDE:

  • S-CW - Supported command which follows CodeWarrior debugger shell syntax
  • P - Command is partially supported, meaning some options/parameters are not supported
  • NA - Command is not applicable in CodeWarrior
  • S-Tcl - Commands is supported in script files with Tcl control flow statements
  • U - Command is not supported
    Table 1. Microcontrollers-Specific Debugger Command List
    CommandStatusDescription
    HIWARE
    VERS-CWLists the version of all loaded commands

    Syntax

    about

    AUTOSIZENASelects window sizing mode
    OPENIONALoads an IO simulation component
    OPENPROJECTUOpens an existing project
    OPENNAOpens a component window
    SETULoads a target component
    LOADULoads an application (Code & Symbols)
    LOADCODEULoads an application (Code only)
    LOADSYMBOLSS-CWLoads an application (Symbols only)

    Syntax

    loadsym <filename>

    FONTUChanges font in component windows
    BCKCOLORUChanges background color of component windows
    SLAYNASaves the layout and options of all components
    ACTIVATENAActivates a window component (in/out focus)
    CLOSENACloses a component window
    SYSTEMS-CWExecutes an external application

    Syntax

    system <command>

    EXITS-CWTerminates this application

    Syntax

    quitIDE

    RESETS-CWResets the target MCU SyntaxReset
    HELPS-CWLists available commands; to get help on a specific command, use the command followed by '?'

    Syntax

    help

    help <command><command> ?

    HIWARE Engine
    LFS-CWOpens a log file

    Syntax (for command)

    log c <file>

    Syntax (for session)

    log s <file>

    NOLFS-CWCloses a log file

    Syntax (for command)

    log off c

    Syntax (for session)

    log off s

    CRURecords all commands to a file
    NOCRUStops recording commands to a file
    LOGS-CWSpecifies items to be logged

    Syntax (for command)

    log c <file>

    Syntax (for session)

    log s <file>

    BSPSets breakpoint

    Syntax

    bp [-{hw|sw|auto}] {<func>|[<ms>:]<addr>|<file> <line> [<column>]}

    bp all|#<id>|<func>|<addr> enable|disable|{ignore <count>}

    bp #<id> cond <c-expr>

    SAVEBPUSaves breakpoints into a file
    STEPINTOS-CWStep Into

    Syntax

    step [asm|src] into

    STEPOUTS-CWStep out

    Syntax

    step [asm|src] out

    STEPOVERS-CWStep over

    Syntax

    step [asm|src] over

    RESTARTS-CWRestart execution

    Syntax

    restart

    DDEPROTOCOLUDDE Protocol options
    DEFINEVALUEDLGUOpens a GUI to define a value for the symbol/variable given as parameter
    BCS-CWClears breakpoint

    Syntax

    bp all|#<id>|<func>|<addr> off

    BDS-CWLists breakpoints

    Syntax

    bp

    GOS-CWStarts execution (Go)

    Syntax

    go

    STOPS-CWStops execution (Halt)

    Syntax

    stop

    PS-CWExecutes an instruction (Flat step)

    Syntax

    stepi

    TS-CWExecutes CPU instructions

    Syntax

    stepi

    Configuration Example
    • radix x
    • config MemIdentifier 0
    • config MemWidth 32
    • config MemAccess 32
    • config MemSwap off
    Note : These options apply only to the memory commands below.
    WBS-CWWrites byte(s) into target memory

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] =<value>

    WWS-CWWrites word(s) into target memory (2 bytes)

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] =<value>

    WLS-CWWrites long(s) into target memory (4 bytes)

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] =<value>

    MSS-CWWrites byte(s) into target memory (same as WB)

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] =<value>

    RDS-CWLists registers

    Syntax

    reg all

    RSS-CWSets registers

    Syntax

    reg <reg-spec>{..<reg>|#<n>} [-s|-ns] [%<conv>] =<value>

    MEMULists memory map
    DASMS-CWDisassembles target memory

    Syntax

    disassemble pc|[<ms>:]<addr> [<count>]

    DBS-CWLists byte(s) from target memory

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] [-np]

    DWS-CWLists words from target memory (2 bytes)

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] [-np]

    DLS-CWLists long(s) from target memory (4 bytes )

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] [-np]

    CDS-CWLists or changes directory

    Syntax

    cd

    ES-CWEvaluates an expression and lists its result

    Syntax

    evaluate [#<format>] [-l] [<var|expr>]

    AS-CWEvaluates an expression and assigns its result to an existing variable

    Syntax

    var <var-spec> [-s|-ns] [%<conv>]=[evaluate [#<format>] [-l] [<var|expr>]]

    Example

    var myVar = [evaluate 1+1] - assigns value "2" to "myVar"

    PRINTFUDisplay a string on the window using printf like format
    FPRINTFUWrite a string to a file using fprintf like format
    NBS-CWChanges or displays the default number base for the value of expressions

    Syntax

    evaluate [#<format>] [-l] [<var|expr>]

    LSULists also global variables and procedures of the loaded application
    SRECPLoads of Motorola S-records from a specified file

    Syntax

    restore -h *.lod [[<ms>:]<addr>|+<offset>] [8bit|16bit|32bit|64bit]

    restore -b *.lod [<ms>:]<addr> [8bit|16bit|32bit|64bit]

    SAVES-CWSaves a specified block of memory to a specified file in Motorola S-record format

    Syntax

    save -h|-b [<ms>:]<addr>... <filename> [-a|-o] [8bit|16bit|32bit|64bit]

    PAUSETEXTNADisplays a modal message box for testing purpose
    TESTBOXNADisplays a modal message box with a given string
    REGFILEULoads the I/O register descriptions from a 'register file'
    REGBASEUSets the base address of the on-chip I/O registers
    ANDBUBitwise-AND with target memory byte
    ANDWUBitwise-AND with target memory word (2 bytes)
    ANDLUBitwise-AND with target memory long (4 bytes)
    NANDBUBitwise-NAND with target memory byte
    NANDWUBitwise-NAND with target memory word (2 bytes)
    NANDLUBitwise-NAND with target memory long (4 bytes)
    ORBUBitwise-OR with target memory byte
    ORWUBitwise-OR with target memory word (2 bytes)
    ORLUBitwise-OR with target memory long (4 bytes)
    NORBUBitwise-NOR with target memory byte
    NORWUBitwise-NOR with target memory word (2 bytes)
    NORLUBitwise-NOR with target memory long (4 bytes)
    EXORBUBitwise-EXOR with target memory byte
    EXORWUBitwise-EXOR with target memory word (2 bytes)
    EXORLUBitwise-EXOR with target memory long (4 bytes)
    MEMCOPYS-CWCopies the target memory
    MEMBITCOPYS-CWCopies one bit from one memory address to another bit to another memory address

    Syntax

    copy [<ms>:]<addr>[..<addr>|#<bytes>] [<ms>:]<addr>

    DEFINES-CWDefines a symbol and associates a value

    Syntax

    set varName ?value? <Tcl command>

    UNDEFS-CWRemoves a symbol definition

    Syntax

    unset varName <Tcl command>

    RETURNUTerminates the current command processing level
    GOTOUGoes to the line following the label
    GOTOIFUGoes to the line following the label if condition is TRUE
    WHILES-TclExecutes commands as long as the condition is true
    FORS-TclExecutes commands up to a predefined number of times
    REPEATS-TclExecutes commands until a certain condition is true
    IFS-TclExecutes different command sections depending on the conditions
    FOCUSNAAssigns a component as the destination for all subsequent commands
    WAITS-CWWaits by time tenths of a second

    Syntax

    wait

    ATUExecutes the next command at time (in ms)
    CFS-CWExecutes commands in the specified command file
    CALLS-CWExecutes commands in the specified command file

    Syntax

    source

    Source
    SPCNAHighlights the statement corresponding to the code address
    SMEMNAHighlights the statements corresponding to the code address range
    SMODNALoads the corresponding module's source text
    SPROCNAHighlights the statement of the procedure that is in the procedure chain
    FOLDNAHides source text for clearness at program block level
    UNFOLDNAExhibits the contents of folded source text blocks
    SLINENADisplays the line
    FINDPROCNAFind the Procedure
    FINDNASearches an arbitrary pattern in the currently loaded source file
    ATTRIBUTESNASets up the display
    Assembly
    SPCNALists the specified address
    SMEMNALists the specified address
    ATTRIBUTESNASets up the display
    Procedure
    ATTRIBUTESNASets up the display
    Register
    ATTRIBUTESNASets up the display
    Memory
    SPCNALists the address given as an argument
    SMEMNALists the memory range given as an argument
    SMODNALists the first global variable of the module
    FILLS-CWFills a memory range with the given value

    Syntax

    mem <addr-spec> [<range>] [-s|-ns] [%<conv>] =<value>

    UPDATERATENASets the update rate
    ATTRIBUTESNASets up the display
    COPYMEMS-CWCopies a memory range to a specified location

    Syntax

    copy [<ms>:]<addr>[..<addr>|#<bytes>] [<ms>:]<addr>

    SEARCHPATTERNNASearch a pattern in memory
    REFRESHMEMORYS-CWAfter releasing caches, refreshes the memory

    Syntax

    refresh

    Data
    SPROCNADisplays local or global variables of the procedure given as parameter
    ADDXPRNAAdds a new expression in the data component
    PTRARRAYNASwitches on or off the pointer as array displaying
    SMODNADisplays global variables of the module given as parameter
    ZOOMNAExhibits the member fields of structures by 'diving' into the structure
    UPDATERATENASets the update rate of the data component
    DUMPPDumps the content of the data component to the command line

    Syntax

    display

    ATTRIBUTESNASets up the display
    REFRESHDATAS-CWAfter releasing caches, refreshes the display

    Syntax

    refresh

    Command
    CLRS-CWClears the Command window

    Syntax

    cls

    ATTRIBUTESNASets up the display
0 Kudos

1,210 Views
manishsangram
Contributor IV

Hi Ladislav,

That is great info. Please note that all the Codewarrior links you provided do not work because on launching each one goes to '127.0.0.1' !!! I tried getting to the NXP site and finding them myself but gave up after lot of navigation not yielding any result. Could you please check this and post the links again?

I see that TCL/TK is used in the debugger window so scripting there will not be a problem.

I have a related question. Is there a free tool we can use for loading the ELF file without the IDE. As an example we want to have some laptops which can carry the latest software to the field and update the same using PE/Universal etc. (We don't use bootloader) but when doing so we want to run a script also which would store the date and time from the PC to the FLASH and do some other updates. Ideally it would be great if it could also debug. Any free GUI or command line tool would be fine. 

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

So here it is.

I am going to start that Device ID is placed on the address 0x1FC000 which is not presented in the documentation because it is internal number which reason is hidden to public.

 

I have created two command files you can run in the debugger window – see and test attached project.

They are AAA_Read_Device_ID_And_OTPROM.cmd  and AAA_ProgramOnceField.cmd.

The project which also present reading and writing program once field is not relevant but should be created for the device we want to play with. It is not required to be code (simple code, enough to use what is generated by wizard) loaded into the MCU’s memory. However, necessary is the debugger is connected to a memory. Because of this it is enough to set:

 pastedImage_1.png

pastedImage_3.png

…. And press debug

 

In the debug enable “Debugger Shell”:

pastedImage_4.png 

Before continuing please modify flash clock setup in both files to value suitable for programming on the basis of the oscclk you use. In the files search for lines

 pastedImage_5.png

 Write into debugger shell command which runs the AAA_Read_Device_ID_And_OTPROM.cmd:

source "c:\D\CODING & SW\ECLIPSE\S12ZVMC-FLASH-WRITEONCEFIELD-CW106\AAA_Read_Device_ID_And_OTPROM.cmd"

(it is possible you have different path to the file…please change it)

 

The command will execute and shows:

Device ID

And Program field phrase 0. If you want to see another phrase you should modify AAA_Read_Device_ID_And_OTPROM.cmd line set PHRASE 1.

pastedImage_6.png

Change 1 to the phrase you want to see and run the command presented above “source …..” again. It is enough to press arrow up on the keyboard to see and use previous commands.

 

In order to program selected field use and run command “source” with the file:

AAA_ProgramOnceField.cmd

source "c:\D\CODING & SW\ECLIPSE\S12ZVMC-FLASH-WRITEONCEFIELD-CW106\AAA_ProgramOnceField.cmd"

 

The same note, the path you have could be different so adjust it.

The same line as in previous file should be changed to select the phrase you want to program.

pastedImage_7.png

As a result you will see programming algorithm and also read back of the field, example of output:

%>source "c:\D\CODING &

SW\ECLIPSE\S12ZVMC-FLASH-WRITEONC

EFIELD-CW106\AAA_ProgramOnceField

.cmd"

############################

Programming Field =

2

############################

cmdwin::mem 0x0386 %x = 0x30

cmdwin::wait 1000

cmdwin::mem 0x0382 %x = 0x05

cmdwin::mem 0x038C %x = 0x07

cmdwin::mem 0x038D %x = 0x00

cmdwin::mem 0x038E %x = 0x00

cmdwin::mem 0x038F %x = 2

cmdwin::mem 0x0390 %x = 0xA2

cmdwin::mem 0x0391 %x = 0xB2

cmdwin::mem 0x0392 %x = 0xC2

cmdwin::mem 0x0393 %x = 0xD2

cmdwin::mem 0x0394 %x = 0xE2

cmdwin::mem 0x0395 %x = 0xF2

cmdwin::mem 0x0396 %x = 0xA3

cmdwin::mem 0x0397 %x = 0xB3

cmdwin::mem 0x0386 %x = 0x80

cmdwin::wait 1000

############################

Read back Programmed Field =

2

############################

cmdwin::mem 0x0386 %x = 0x30

cmdwin::wait 1000

cmdwin::mem 0x0382 %x = 0x01

cmdwin::mem 0x038C %x = 0x04

cmdwin::mem 0x038D %x = 0x00

cmdwin::mem 0x038E %x = 0x00

cmdwin::mem 0x038F %x = 2

cmdwin::mem 0x0386 %x = 0x80

cmdwin::wait 1000

cmdwin::mem 0x0390 8

     390  $a2 $b2 $c2 $d2 $e2 $f2

 $a3 $b3   . . . . . . . . 

 

 

….Are you able to test? Do you understand?

Best regards,

Ladislav

0 Kudos

1,210 Views
manishsangram
Contributor IV

Hi,

I have not tried writing and reading the OTP, but I tried getting the Device ID using the command

mem 0x1FC000, this only provides a single byte. How long is the device id?  I can see upto xxx09 are bytes followed by 0xFF.

Also for memory following this address, I can see a lot more data up to 1FC0BF. Is there any documentation for all of this?

Is there a PDF reference for all the scripting commands? I tried looking up PE Micro site but could not find the right document. I was looking at  CPROGS12ZZ User Guide v.1.00 and      PROGS12ZZ User Manual v.1.00 (.pdf)

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

1) The memory is program once and read anytime. You can really read it anytime you want. The programming the field is possible only once for each phrase. It is OTPROM. No mass erase or another command can return the status of the phrase back to erased status.

2) The chip ID is unique as I wrote before. However, the meaning is hidden for public.

3) Theoretically, the only thing which would be the safest for you is to safely damage BKGD pin to disable any connection to the MCU in the future when it is programmed. I have never heard about this possibility and please do not think about it as a real solution. This is only imagination.

4) If I think about security. We have to believe the security is working because if I accept fact there is some possibility to read the code via BDM then there is also possibility to analyze this code and get info about security actions….what is being read, what is being compared

5) BTW, the ID can be simply read by command flow in command window window as well as it can be added to preload file before programming the phrase
//--- Read ID ---

 

WB MMCCTL1 0x10       // enable ROM memory 0x40_0000

DW 0x400000'G,4          // get ID

WB MMCCTL1 0x00       // disable ROM memory 0x40_0000

Best regards,

Ladislav

0 Kudos

1,210 Views
manishsangram
Contributor IV

Hi Ladislav

Thanks for your very helpful and useful responses.

I understand now that ReadOnce is only a command name but it can read the values written in the Write Once area any number of times. I also understand that the Write Once area can only be written to once and never erased once written even if the device is mass erased.

Please confirm that the above understanding is correct.

In point 2 you write that there is a CHIP ID, and that's great, we don't care about the meaning as long as it is unique per physical chip.

In point 5 the address you have given is that of the CHIP ID? 

We are using the PEMicro Multilink Universal programmer and we can't find any 'console' or command line tool in Codewarrior to execute this script. Could you guide us on how / where this is? Also if we could insert such a script during programming (even for production) we would be able to write current date etc from the PC to the firmware? Is there any document you can point us to for this?

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

ups, there is misunderstanding. I have been all the time talking about S12XEP device and having checked it back I found you use S12ZVM. I'll must go to beginning and prepare a new answer. I am solving a few similar things with different MCUs in parallel so an information mix happened in my mind.

I am really sorry. Probably I will also erase messages which could confuse someone.

Best regards,

Ladislav

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

I've been looking on information about this and NXP position is that:

No security feature is absolutely secure. However, NXP’s strategy is to make reading or copying the FLASH and/or EEPROM difficult for unauthorized users.

 

There is no special ID, however you can use write once field to create specific device.

Currently I do not have example for S12ZVM device but you can use https://community.nxp.com/message/864084 as a helping hand to continue.

There are two ways to program the field.

The first one requires special BDM code, I do not know whether such a code exists.

The second approach is to program the device with own code which writes this field (20.4.7.6 Program Once Command) after first execution and then clear the flash and write application code into it.

 

Before I found already existing example I created my own see attachment.

It is a little bit extended version of https://community.nxp.com/docs/DOC-334388.

 

Best regards,

Ladislav

1,210 Views
manishsangram
Contributor IV

Hello Ladislav,

Is this memory write once / read once during the life of the MCU or till it is fully erased by a programmer? Checking this before trying it out on our board :smileyhappy:.

Is there any suggested strategy(ies) on how to use this effectively?

This question is more like even if I write once and read once, how can I use it to ensure that my code (even if copied) detects this? because if I write any code which checks this it cannot check every time it boots but only the first time and if it set's any flag the flag will get copied when someone copies the Flash and EEPROM.

0 Kudos

1,210 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

I see the best way is to load phrase while you program the device by script of the programmer. In this way the programming of the field is not a part of application and you only test the phrase for correct value written into it.

As an example I have prepared for you a short code which contains adjusted preload.cmd file and ask for phrase you want to program in the OTPROM before application download. I have attached the project with the file. You can test.

preload.cmd file content:

DEFINEVALUEDLG "Information required to write phrase X of OTPROM" "FCLKDIV" 17 "To program it, the command script needs \nthe correct value for the FCLKDIV onchip register.\n\nDatasheet proposed values:\n\noscillator frequency\tFCLKDIV value (decimal)\n\n 16 \tMHz\t\t17\n 12 \tMHz\t\t13\n  8 \tMHz\t\t9\n  4 \tMHz\t\t5\n"

DEFINEVALUEDLG "Select phrase you want to program" "PHRASE" 0 "Phrase from 0 to 7 should be selected"

FLASH RELEASE

wb 0x03c 0x00  //disable cop
wait 20
                    
WB 0x100 FCLKDIV // clock divider for 16MHz OSCCLK
WB 0x013 0x10   // enable ROM memory 0x40_0000

WB 0x013 0x10   // enable ROM memory 0x40_0000
WB 0x106 0x30   // clear any error flags       FSTAT = 0x30
WB 0x102 0x00   // CCOBIX = 0                  FCCOBIX = 0x00
WB 0x10A 0x07   // load program command        FCCOBHI = 0x07
WB 0x10B 0x00   // load program command        FCCOBLO = 0x00
WB 0x102 0x01   // CCOBIX = 1                  FCCOBIX = 0x01
WB 0x10A 0x00   // load phrase Hi value        FCCOBHI = 0x00   / phrase 0x0000
WB 0x10B PHRASE // load phrase Lo value        FCCOBLO = 0xPHRASE
WB 0x102 0x02   // CCOBIX = 2
WB 0x10A 0xDE   // load data
WB 0x10B 0xAD   // load data
WB 0x102 0x03   // CCOBIX = 3
WB 0x10A 0xC0   // load data
WB 0x10B 0xDE   // load data
WB 0x102 0x04   // CCOBIX = 4
WB 0x10A 0xBE   // load data
WB 0x10B 0xEF   // load data
WB 0x102 0x05   // CCOBIX = 5
WB 0x10A 0xF0   // load data
WB 0x10B 0xF0   // load data
WB 0x106 0x80   // launch command
WAIT 1


WB 0x013 0x00   // disable ROM memory 0x40_0000

undef FCLKDIV
undef PHRASE

Best regards,

Ladislav

1,210 Views
manishsangram
Contributor IV

Hello Ladislav,

 

1) Can you answer this part of my previous comment :

"Is this memory write once / read once during the life of the MCU or till it is fully erased by a programmer?"

2) The solution you have outlined in the previous comment is great, but it won't prevent the firmware from being copied as outlined below.

a) Even if some bytes were written, they can only be read once. So I read it on boot up and set a flag in EEPROM / Flash that the firmware is authentic. Now when someone copies the firmware illegally this flag will also be copied.

 

Now IF there was a CHIP ID unique to each physical device 

b) We could have read this id (by programmer) and written it back in FLASH (encrypted) and check it on power up so that if someone copied it the verification would fail except on the chip it was originally programmed.

So far I cannot see how I can use this write once / read once feature to do a run time check to verify if the firmware was authentically written or illegally copied.

0 Kudos