This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF52840 Cryptocell register setting reading problem

I am trying to set the Lifecycle state of the cryptocell, but it seems like I am having an issue.

I do 


/** Enable crypto cell to configure it **/
NRF_CRYPTOCELL->ENABLE = CRYPTOCELL_ENABLE_ENABLE_Enabled << CRYPTOCELL_ENABLE_ENABLE_Pos;

/** Config cryptocell resgister so Device root key can only be set once per reset*/
NRF_CC_HOST_RGF->HOST_IOT_LCS = CC_HOST_RGF_HOST_IOT_LCS_LCS_Secure << CC_HOST_RGF_HOST_IOT_LCS_LCS_Pos;

/** Disable crypto cell until next use**/
NRF_CRYPTOCELL->ENABLE = CRYPTOCELL_ENABLE_ENABLE_Disabled << CRYPTOCELL_ENABLE_ENABLE_Pos;

But then later when I enable the cryptocell again and read the value of HOST_IOT_LCS,

LCS is 2 (like I expected) but LCS_IS_VALID is 0 which means invalid.

Any ideas?

I am using zephyr and I am doing this configuration post kernel with a priority after CONFIG_KERNEL_INIT_PRIORITY_DEFAULT. So the cryptocell is already being initialized by hw_cc310_init in file hw_cc310.c

  • Hello,

    There may be a problem with the LCS_IS_VALID register and/or always-on power domain. We need to look a bit more into this, but I will update you as soon as possible (hopefully tomorrow).

  • I think maybe the issue is fixed. But I'm not sure. The behavior seems to depend how I debug.

    First I changed one thing. I was doing this register setting before the flash device was initialized. So I changed it to happen after (not really related to this register setting but for something else I am doing in the same function).

    Now when I set the register, it still goes fine LCS_IS_VALID is 1 and LCS is 2 (I see that after I set the register but before I disable). Then when I enable the cryptocell again if I step my debugger through the lines (shown in my original post) where I set the register I see LCS_IS_VALID is 1 and LCS is 2 in the register. But if I don't step my debugger though those lines and later I enable the cryptocell and look at the value of the register  in the debuger LCS_IS_VALID is 1 and LCS is 0.

    So this is probably just a debugger issue at this point ( I am using nordic connect SES with a J-trace pro). But I'm not sure. I guess the only way to tell for sure will be to encrypt something with the root key then try to change the root key, and encrypt again, and see if the result is the same. 

  • Also the documentation doesn't really mention this (I don't think) but to be clear, if I want to write to or read from CC_HOST_RGF the cryptocell must be enabled correct. It seems that way but I only figured that out by trial and error.

  • Sorry about so many posts, but I think I have another thing that is contributing to the issue. This code is executing in a bootloader whose partition is from 0 to 0x22000. Another protection I implement in the bootloader is to use ACL[0] to protect the bootloader from writes. I use this code

    NRF_ACL->ACL[0].ADDR = 0;
    NRF_ACL->ACL[0].PERM = ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos; // 0x2
    NRF_ACL->ACL[0].SIZE = DT_FLASH_AREA_MCUBOOT_SIZE;  // this is 0x22000

    When I do this before I write the LCS register, I get the behavior I described in my original post. If I don't write to this ACL i get he behavior from my second post.

    I don't see how this ACL code affects the writing to the NRF_CRYPTOCELL, or NRF_CC_HOST_RGF

    I also notice that if I do the ACL setup before I write the LCS resgister, and I have more than 5 break points set anywhere in the code. Then I try to step past a line in the disassembly that stores a value to either the RF_CRYPTOCELL->ENABLE register or the NRF_CC_HOST_RGF->HOST_IOT_LCS register,  SES takes a long time and then SES spits out a message saying something like 

    "Timeout while erasing sectors, RAMCode did not respond in time. (PC = 0x00000000, CPSR = 0x00000000, LR = 0x01000005)!
    Failed to erase sectors.
    Programming failed @ address 0x00001A50 (block verification error)"

    Sometimes execution stays at the line  and does not execute it, sometimes execution goes past it

    If I have no debug points the code runs fine. 

    These are software breakpoints. 

    If I remove the ACL protection I can use as many breakpoints as I want and there is no timeout problems. 

  • Hi,

    Yes, you are right. The documentation is unclear on this.

    And about the original question, it seems you are right on that point tas well.  The LCS_IS_VALID is a read-only field, but if you write to it, this will make it 1 regardless of what you write. It is intended to show if LCS is set, which is the only field in HOST_IOT_LCS that should be written to.

    So in short, any writing to any part of the HOST_IOT_LCS register sets the LCS_IS_VALID field to 1.

Related