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

Two issues with CC310 HW CryptoCell: Linking and hanging

Hi, we stumbled into two issues when we enabled LESC in our application.

Relevant SDK config:

NRF_CRYPTO_ENABLED

NRF_CRYPTO_BACKEND_CC310_ENABLED

NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED

First one is that pm_init() will hang if called when NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED unless we call sd_nvic_critical_region_enter before and then sd_nvic_critical_region_exit after. I can't find anything documentation saying that we need to do that. See attached stacktrace when calling pm_init() without entering critical region. It's the CRYS_RndInit() which hangs and causes the WD to reset.

Second issue I think is related to linking. 

I have a theory that the linker does not link cc310_backend_init.o file as the two public functions void cc310_backend_enable(void); and void cc310_backend_disable(void); are
found in cc310_backend_shared.c and therefore CRYPTO_BACKEND_REGISTER does not
place cc310_backend_init and cc310_backend_uninit in the crypto_data section in flash.

Causing that cc310_backend_init() is never called when initiating as it's not found in the.crypto_data 

If I add a dummy function to cc310_backend_init.c the two functions are placed in the .crypto_data section in the flash. See the attached patch.txt file.


diff --git a/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/backend/cc310/cc310_backend_init.c b/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/backend/cc310/cc310_backend_init.c
index e3e77f0b..05f29edb 100644
--- a/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/backend/cc310/cc310_backend_init.c
+++ b/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/backend/cc310/cc310_backend_init.c
@@ -57,6 +57,18 @@ void cc310_backend_enable(void);
  */
 void cc310_backend_disable(void);
 
+// patch start
+uint32_t forceLinkingcc310BackendInit()
+{
+    /*
+    The linker does not link this file as the above two functions are found in cc310_backend_shared.c
+    And therefore CRYPTO_BACKEND_REGISTER does not place cc310_backend_init cc310_backend_uninit 
+    in the crypto_data section in flash. This is a workaround for not ignoring this file.
+    */
+    return 0;
+}
+//patch end
+
 static uint32_t init_result_get(uint32_t crys_error)
 {
     uint32_t ret_val = NRF_ERROR_INTERNAL;
     
--- a/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.c
+++ b/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.c
@@ -79,6 +79,11 @@ ret_code_t nrf_crypto_init(void)
             return ret_val;
         }
     }
+    // patch start
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+    forceLinkingcc310BackendInit();
+#endif
+    // patch end
 
     // Set nrf_crypto to initialized
     m_state = INITIALIZED;
diff --git a/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.h b/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.h
index 8e10ae13..a90125b0 100644
--- a/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.h
+++ b/bsp/nRF5_SDK_15.2.0_9412b96/components/libraries/crypto/nrf_crypto_init.h
@@ -136,6 +136,10 @@ bool nrf_crypto_is_initialized(void);
  */
 bool nrf_crypto_is_initializing(void);
 
+// patch start
+uint32_t forceLinkingcc310BackendInit();
+// patch end
+
 #ifdef __cplusplus
 }
 #endif

SoftDevice: s140_nrf52_6.1.0

SDK: nRF5_SDK_15.2.0_9412b96

  • Ah, yes, you're right. The SDK is built and linked as a static library.

    This might be of an esoteric nature, but do you have any clue at all why it then works by adding a call to the dummy function?

    Thanks for all help! / Peter

  • That is probably the explanation, then. I recommend you stop building the SDK as a library, as that has been known to cause several problems. The dummy function probably works because it make the linker aware that the function is being used (it is missing from the section variable where it should have been), and that causes it to include it.

  • I had the same problem as OP which was solved by his patches. Running nRF52840 with SDK 15.3. Really annoying since it took like 5h to figure it out. I'm using Segger Embedded Studio v4.10. Note that I'm not building the SDK as its separate library hence the upvoted green answer to this thread did not help in my case. 

  • I've just had the same problem, nrf_crypto_rng_init hangs in CRYS_RndInit.

    Not building SDK as a separate library.

    After a couple of hours I found out it occurs as soon as I reference nrf_crypto_ecc_public_key_calculate() in my code.

    (nrf_crypto_ecc_public_key_calculate will not work apparently with the cc310 backend, because it is not implemented by that backend, but because of the crypto init hanging, I never got to that point in my code where I even tried to call that function, and find out it was not implemented)

    Just linking that function causes CRYS_RndInit to hang.

    Now that I've removed the reference to nrf_crypto_ecc_public_key_calculate, nrf_crypto_rng_init works fine again, CRYS_RndInit no longer hangs.

    Just posting this for reference, in case someone else gets into the same situation some day.

    My problem has been resolved (by avoiding nrf_crypto_ecc_public_key_calculate), so no action needed.

    Unless someone perhaps could clarify what happens here, because it puzzles me.

  • Unfortunately, the problem has come back, nrf_crpyto_rng_init hangs in CRYS_RndInit again.

    Even without having nrf_crypto_ecc_public_key_calculate in my code, which does not appear to be causing the problem after all (even though adding/removing it several times reproduced/removed the issue for sure)

    I've tried to add sd_nvic_critical_region_enter/exit around nrf_crypto_init and nrf_crypto_rng_init which apparently helped the OP, but that does not help in my case.

    When I comment all of my nrf_crypto_ecc code, the problem disappears. Again, none of this code has been executed yet by the time CRYS_RndInit hangs, because this occurs in nrf_crypto_init (which calls nrf_crypto_rng_init internally because of NRF_CRYPTO_RNG_AUTO_INIT_ENABLED), way before anything interesting happens.

    I do notice that before CRYS_RndInit is going to hang, when I start the application in the debugger, SEGGER IDE shows "Erasing range 0x41000-0x41FFF" and blocks for about 10s (erasing a single page normally does not take that long).

    Whenever erasing (because of reprogramming) a single page takes that long, I already know CRYS_RndInit is going to hang.

Related