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

NRF52840 and CC310 Random number generator hanging.

Hi,

Due to several reasons, we can't use the crypto API:s provided by the NRF_SDK (version 15.00) so we are creating a "driver" for direct access of the CC310 via the CRYS_* API:s available in ARM:s crypto library that is available in the before mentioned SDK version.

The AES crypto stuff is working as expected, but the RNG is behaving very badly.

In case 1, when we run Zephyr, the RNG hang in the function "CRYS_RndInit". I have not run this throug a debugger, so I have no additional information about this.

In case 2, when we use the nrf_sdk, the function "CRYS_RND_Reseeding" hangs in "SaSi_HalWaitInterrupt() at 0x3c342". AS far as I understand, the reseeding is required to get different  random numbers. At least, I continually get the same random number from the chip when not re-seeding.

Since I no longer have access the source code for ARM's cryptocell library, it's quite difficult for me to debug this. There must be something simple that I'm missing here (both for Zephyr and NRF_SDK).

Please advise since this is currently blocking the continuation of our porting.

This is the code that is running:

--- CUT AND PASTE ---

#include "crys_rnd.h"
#include "nrf52840.h"
#include "sns_silib.h"

int cc310_init(void)
{
        NVIC_EnableIRQ(CRYPTOCELL_IRQn);
        NRF_CRYPTOCELL->ENABLE = 1;

        ret = SaSi_LibInit();
        if (ret != SA_SILIB_RET_OK) {
                LOGE("Failed SaSi_LibInit - ret = 0x%x\n", ret);
                return HAL_RES_ERROR;
        }

        ret = CRYS_RndInit(&rndState, &rndWorkBuff);
        if (ret != SA_SILIB_RET_OK) {
                LOGE("Failed CRYS_RndInit - ret = 0x%x\n", ret);
                return HAL_RES_ERROR;
        }

        ret = CRYS_RND_Instantiation(&rndState, &rndWorkBuff);
        if (ret != SA_SILIB_RET_OK) {
                LOGE("Failed CRYS_RND_Instantiation - ret = 0x%x\n", ret);
                return HAL_RES_ERROR;
        }

        return 0;
}

int cc310_getRnd(uint32_t *const randomNumber)
{
        static uint8_t rand[sizeof(uint32_t)] = { 0 };
        int err = HAL_RES_OK;
        *randomNumber = 0;

        CRYS_RND_AddAdditionalInput(&rndState, rand, sizeof(rand));

        err = CRYS_RND_Reseeding(&rndState, &rndWorkBuff);
        if (SA_SILIB_RET_OK != err) {
                LOGE("Failed to re-seed the random number generator. Aborting");
                err = HAL_RES_ERROR;
                goto fail;
        }

        err = CRYS_RND_GenerateVector(&rndState, sizeof(uint32_t), rand);
        if (SA_SILIB_RET_OK != err) {
                LOGE("Failed to generate a random number. Aborting");
                err = HAL_RES_ERROR;
                goto fail;
        }

        *randomNumber = (uint32_t)rand;
        err = HAL_RES_OK;

fail:
        return err;
}

--- END CUT AND PASTE ---

Parents
  • Hi,

    I managed to get the crypto working on Zephyr as well by adding the following in my init function:

    Not quite sure about the IRQ priority (0) though and would like a confirmation on this one.

    #ifdef __ZEPHYR__
            extern void CRYPTOCELL_IRQHandler(void *);
            IRQ_DIRECT_CONNECT(CRYPTOCELL_IRQn, 0, CRYPTOCELL_IRQHandler, 0);
    #endif

Reply
  • Hi,

    I managed to get the crypto working on Zephyr as well by adding the following in my init function:

    Not quite sure about the IRQ priority (0) though and would like a confirmation on this one.

    #ifdef __ZEPHYR__
            extern void CRYPTOCELL_IRQHandler(void *);
            IRQ_DIRECT_CONNECT(CRYPTOCELL_IRQn, 0, CRYPTOCELL_IRQHandler, 0);
    #endif

Children
  • Hi,

    I am glad to hear you got it working on Zephyr. The current CC310 runtime library has not been ported for Zephyr, and we expect there to be some issues. There will be a new runtime library which at some point, but I do not have a time frame for it.

    Regarding the nRF5 issue I am a bit puzzled on how you use it (like reseeding every time), and missing some context. As mentioned I suggest you look at the implementation in cc310_backend_rng.c in the nRF5 SDK. If you still have problems, then it would be interesting to see more of your code so that I can know exactly how you configure and use CC310 and test on my side.

  • As I've stated, I've only got AES crypto to work on Zephyr. :-)

    The RNG, is not working as expected. I've tried to seed it after initialization only (testing with a uint32, which is far from optimal), but it always generates the same value from it. This is not what I expected. Even if it's only seeded with something primitive, I did expect it to at least generate different numbers on different calls. Since we have not been able to get any useful data from it, the code is not tested and verified.

    With regards to NRF-SDK, I still get stuck waiting for an interrupt when trying to seed the RNG. Based on my experiences with Zephyr, I assume that the correct IRQ handler is not installed on NRF-SDK.


    Are there any special flags that need to be set in order to install the correct IRQ handler for the cryptocell?

  • jocke said:
    As I've stated, I've only got AES crypto to work on Zephyr. :-)

    OK. I misread your previous post then. As mentioned we do not support the CC310 runtime library with Zephyr at the moment, but work is ongoing and we will release something in the not too distant future.

    jocke said:
    With regards to NRF-SDK, I still get stuck waiting for an interrupt when trying to seed the RNG. Based on my experiences with Zephyr, I assume that the correct IRQ handler is not installed on NRF-SDK.

    That should not be the case. The nRF5 SDK doe snot implement the ISR, it is only implemented in the CC310 library. As long as you have kept the default startup file you should see CRYPTOCELL_IRQHandler there, and the linker should pick it form the CC310 library without any problems.

    jocke said:
    Are there any special flags that need to be set in order to install the correct IRQ handler for the cryptocell?

     No. The only idea I have, which is a long shot, is that we have seen strange linker behavior with GCC 7 and LTO, where it sometimes fails to include the IRQ handler. If you are using that, can you try with GCC 6 or disable LTO?

  • Hi,
    Switching from GCC-8 to GCC-6 seems to have solved the problem.
    RNG is now working as expected.

  • Hi,

    I am glad to hear you found the problem. Thank you for letting us know that using GCC 6 solved the problem!

Related