Hello,
Using a IMX8QXP-C0, I want to use a tamper (SC_P_CSI_D05_SNVS_TAMPER_IN0).
I saw I could use imx_sc_seco_secvio_config() in order to configure SVNS registers from Linux.
Unfortunately (and strangely!!), this function can access to some SNVS registers (as HPSVCR, LPSR, LPTDSR...) but not at all of them.
Especially, I can not read/write LPTDC2R which is used to configure tampers.
So here is my questions:
- Why could not I read/write some SVNS registers (as LPTDC2R) with imx_sc_seco_secvio_config() function?
- Is there any other way to use tampers?
Thank you for your help.
External Tamper Detection is a special mechanism provided through a chip pin to signal when the device encounters unauthorized opening or tampering. This Linux user space application is a tool that allows tampering configuration and real time monitoring of the most important SNVS registers. Here is an Application Note for i.MX7D: https://www.nxp.com/docs/en/application-note/AN12210.pdf
Hope can do help for you
Hello,
I already read this document but unfortunately, it is not for iMX8.
For example, it uses the u-boot command "fuse" but this command seems not working on iMX8.
That is why I tried to access Seco registers directly.
For example, in your documentation (and on the IMX8QXPSRM document), it is written "This register (LPTDCR) cannot be programmed when LPTDCR is locked for write."
Please could you tell me what is locking/unlocking this register?
Unlocking LPTDCR will unlock LPTDC2R which could solve my problem.
The registers can be configured as below:
It is possible to show the status (values) of the fuses related to tamper and security violation, the SNVS, the DGO and the pins using the command snvs_sec_status.
It is possible to configure the SNVS using command line (if the flag ‘CONFIG_SNVS_SEC_SC_AUTO’ is not set) using the Uboot commands:
LPTDC2R register can be set by parameter <lp.tamper_det_cfg2>
Example (active tamper):
How did you configure SNVS register in Linux? Can you provide the steps and configuration? Thanks.
Thank you for your answer.
My need is to use tamper 5 (D05_SNVS_TAMPER_IN0) as static.
I am using call_secvio_config() function on linux but I don't mind to work directly on u-boot.
As my snvs_cfg command uses 19 parameters (adding hp.secvio_intcfg parameter), I launch the command:
snvs_cfg 1f0703ff 8000003f 3000007f 1f0003ff 36 00800000 276 0 0 0 84001111 0 0 0 0 00010001 0 1 0
I don't see any difference but after a reset (switch off/switch on the board), the init values have changed:
HPSICR (0C) used to be 8000003f and is now 00000000
LPATCTLR (E0) used to be 001f001f and is now 00000000
Q1: Do you know why init values have changed after this command?
Q2: In this command, why do you put LPTDC2R (A0)=0? Shouldn't it be FF?
Q3: In this command, why do you put "Write access is not allowed" (HPLR + LPLR)?
Q4: If I understand, in order to write on the LPTDC2R register (A0), I have to access LPTDCR (48) with size = 2. Is it correct?
Q5: Which register gives the information tamper 5 has changed? Because changing tamper5 input does change any register.
Here are the results:
=> snvs_sec_status
Pins:
- Pin 141: 18000060
- Pin 142: 00000040
- Pin 143: 00000040
- Pin 144: 00000040
- Pin 145: 00000040
- Pin 136: 00000040
- Pin 137: 00000040
- Pin 138: 00000040
- Pin 139: 00000040
- Pin 140: 00000040
Fuses:
- Fuse 14: 0000421f
- Fuse 30: f470f7c2
- Fuse 31: 0163c003
- Fuse 260: 00000000
- Fuse 261: 00000000
- Fuse 262: 00000000
- Fuse 263: 00000000
- Fuse 768: 00000000
SNVS:
- SNVS 00(1): 00000000
- SNVS 34(1): 00000000
- SNVS 0c(1): 00000000
- SNVS 10(1): 00000000
- SNVS 18(1): 00000000
- SNVS 40(1): 00000008
- SNVS 48(2): 00000000 00000000
- SNVS 4c(1): 80000000
- SNVS a4(1): 00000000
- SNVS 44(3): 00000000 00000000 00000000
- SNVS e0(1): 00000000
- SNVS e4(1): 00000000
- SNVS e8(2): 00000000 00000000
- SNVS 3c(1): 00000000
- SNVS 5c(2): 00000000 00000000
- SNVS 64(1): 41736166
- SNVS f8(2): 003e0103 06000400
DGO:
- DGO 00: 00000000
- DGO 10: 00000000
- DGO 20: 00000000
- DGO 30: 00000000
- DGO 40: 00000000
- DGO 50: 00000000
=> snvs_cfg 1f0703ff 8000003f 3000007f 1f0003ff 36 00800000 276 0 0 0 84001111 0 0 0 0 00010001 0 1 0
=> snvs_sec_status
Pins:
- Pin 141: 18000060
- Pin 142: 00000040
- Pin 143: 00000040
- Pin 144: 00000040
- Pin 145: 00000040
- Pin 136: 00000040
- Pin 137: 00000040
- Pin 138: 00000040
- Pin 139: 00000040
- Pin 140: 00000040
Fuses:
- Fuse 14: 0000421f
- Fuse 30: f470f7c2
- Fuse 31: 0163c003
- Fuse 260: 00000000
- Fuse 261: 00000000
- Fuse 262: 00000000
- Fuse 263: 00000000
- Fuse 768: 00000000
SNVS:
- SNVS 00(1): 1f0703ff
- SNVS 34(1): 1f0003ff
- SNVS 0c(1): 8000003f
- SNVS 10(1): 0000007f
- SNVS 18(1): 80000000
- SNVS 40(1): 0000003e
- SNVS 48(2): 00000276 00000000
- SNVS 4c(1): 80000200
- SNVS a4(1): 00000000
- SNVS 44(3): 00800000 00000000 00000000
- SNVS e0(1): 00010001
- SNVS e4(1): 00000000
- SNVS e8(2): 00000001 00000000
- SNVS 3c(1): 00000000
- SNVS 5c(2): 00000000 00000000
- SNVS 64(1): 41736166
- SNVS f8(2): 003e0103 06000400
DGO:
- DGO 00: 00000000
- DGO 10: 00000000
- DGO 20: 00000000
- DGO 30: 00000000
- DGO 40: 00000000
- DGO 50: 00000000
Thank you for your help.
(1) uboot steps
The previous setting is just an example of active tamper, the registers should be configured as needed.
For example, if you want to use TAMPER_IN0 to check that a tamper connected to ground trigger when the line is opened. The process is like following:
We connect ET1 (tamper 0) to ground, we configure the DGO to PULL UP the line. When the line is cut, we will detect the transition GND to VCC. So, we must configure the detector to detect HIGH voltage.
HW setup: Connect the tamper to ground.
SW Configuration:
Configuration in uboot:
=> tamper_pin_cfg 141 0xdc000060
=> snvs_dgo_cfg 0 401 20000000 0 0 0
=> snvs_cfg 0 0 0 0 0 800000 a00 0 0 0 0 0 0 0 0 0 0 0 0
=> snvs_sec_status <- in default state: tamper 0 connected to ground
Pins:
- Pin 141: 1c000060
- Pin 142: 00000040
- Pin 143: 00000040
- Pin 144: 00000040
- Pin 145: 00000040
- Pin 136: 00000040
- Pin 137: 00000040
- Pin 138: 00000040
- Pin 139: 00000040
- Pin 140: 00000040
Fuses:
- Fuse 14: 0000425f
- Fuse 30: 00000002
- Fuse 31: 1c00001d
- Fuse 260: 00000000
- Fuse 261: 00000000
- Fuse 262: 00000000
- Fuse 263: 00000000
- Fuse 768: 00000000
SNVS:
- SNVS 00(1): 000001c0
- SNVS 34(1): 00000000
- SNVS 0c(1): 00000000
- SNVS 10(1): 00000000
- SNVS 18(1): 00000000
- SNVS 40(1): 00000008
- SNVS 48(2): 00000a00 00000000
- SNVS 4c(1): 80000000 <-The bit “ET1D” in SNVS “LPSR” shall not be set (0x00000200).
- SNVS a4(1): 00000000
- SNVS 44(3): 00800000 00000000 00000000
- SNVS e0(1): 00000000
- SNVS e4(1): 00000000
- SNVS e8(2): 00000000 00000000
- SNVS 3c(1): 00000000
- SNVS 5c(2): 00000000 00000000
- SNVS 64(1): 41736166
- SNVS f8(2): 003e0103 06000400
DGO:
- DGO 00: 00000000
- DGO 10: 00000401
- DGO 20: 20000000
- DGO 30: 00000000
- DGO 40: 00000000
- DGO 50: 00000000
=> snvs_sec_status <- Open the line to trigger tamper
Pins:
- Pin 141: 1c000060
- Pin 142: 00000040
- Pin 143: 00000040
- Pin 144: 00000040
- Pin 145: 00000040
- Pin 136: 00000040
- Pin 137: 00000040
- Pin 138: 00000040
- Pin 139: 00000040
- Pin 140: 00000040
Fuses:
- Fuse 14: 0000425f
- Fuse 30: 00000002
- Fuse 31: 1c00001d
- Fuse 260: 00000000
- Fuse 261: 00000000
- Fuse 262: 00000000
- Fuse 263: 00000000
- Fuse 768: 00000000
SNVS:
- SNVS 00(1): 000001c0
- SNVS 34(1): 00000000
- SNVS 0c(1): 00000000
- SNVS 10(1): 00000000
- SNVS 18(1): 80000000
- SNVS 40(1): 00000008
- SNVS 48(2): 00000a00 00000000
- SNVS 4c(1): 80000200 <-The tamper was trigger and the bit “ET1D” in SNVS “LPSR” was set (0x00000200).
- SNVS a4(1): 00000000
- SNVS 44(3): 00800000 00000000 00000000
- SNVS e0(1): 00000000
- SNVS e4(1): 00000000
- SNVS e8(2): 00000000 00000000
- SNVS 3c(1): 00000000
- SNVS 5c(2): 00000000 00000000
- SNVS 64(1): 41736166
- SNVS f8(2): 003e0103 06000400
DGO:
- DGO 00: 00000000
- DGO 10: 00000401
- DGO 20: 20000000
- DGO 30: 00000000
- DGO 40: 00000000
- DGO 50: 00000000
(2) Linux steps
Have you ever configured LPTDCR(0x48) before in uboot? Because this register can only be written once. The register write access is marked as locked by SECO after the first write through the manage SNVS interface. If you try to write it again in Linux, there should be some error.
Thank you, it is working.
Where could I have some information on DGO registers? Could you provide me a document?
My need is to automatically clear SNVS when the tamper is cut.
Is it possible to read/write SNVS from u-boot commands?
How do I configure tamper registers in order to clear SNVS when there is a violation?
Thank you for your help.
We don't have DGO document for customer. But If they have questions about how to configure, we can help on it.
"Is it possible to read/write SNVS from u-boot commands?"
What SNVS do you mean? If you mean SNVS configuration registers, we can just use snvs_sec_status command in uboot to read and use snvs_cfg to write.
Hello,
No, I don't mean SNVS registers.
SNVS is a memory and I would like to know if it is possible to write or read on this memory with u-boot commands.
If not, what is the easiest way to do that?
Thank you for your help.
The LP ZMK register seems cannot be read. As we tested, GPR2/3 can be written and read successfully by using L4.14.98 BSP. But in the latest lf-5.15.5-1.0.0 version, it cannot be written. I raised a jira ticket about it and to confirm whether SNVS will be cleared: [AHAB-734] Check LPCR register configuration on i.MX8QXP - NXP JIRA
Waiting for internal team's reply.
When we get update I will share to you as soon as possible.
Hello,
Do you have any news?
Thank you for your help.
One update from internal team:
LP ZMK will be cleared automatically after violation.
Hope this can do help you
Hello,
Not really. To come back to my question: I would like to know if it is possible to write or read on the SNVS memory with u-boot commands. If not, what is the easiest way to do that?
Thank you for your help.
@PBR This is update from our expert team:
Could you let customer specify what they mean by SNVS LP memory?
Do they refer to General Purpose Reg? or Zeroizable Master Key?
If I understand, you write a key in the Zeroizable Master Key. If there is a violation, the key in ZMK is cleared.
So yes I mean ZMK.
I want to write a key in ZMK, read it, create a violation and read it again to check ZMK is cleared?
So how to read/write ZMK? Is it possible with u-boot commands?
The Zeroizable Master Key cannot be read directly.
The interface does not support ZMK for the customer to use currently, please ask the customer if there is a specific case that needs to use ZMK.
Here is the customer case.
A secrete data (a key) is written somewhere (ZMK, general purpose register...).
The requirement is: When there is a violation, the data (the key) is automatically destroyed.
I believed ZMK was the right place to put this key but if it cannot be read, it is no use.
So the question: where I can read/write this secrete data and how to do that?
Could you please help to confirm that:
customer's requirement:
1. Use SNVS LP as secure storage to save the key, not limited to ZMK register(because ZMK has other usage).
2. Can read/write the key.
3. When there is a violation, the data (the key) is automatically destroyed.
Could you please ask customer for their project timeline? When will they need this function?
Hello,
Yes, all 3 points are my customer's requirement.
I am not sure when they will need it. But for us, it will be better to give them this feature as soon as we can.