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, nice work finding the problem and workaround(s).

    I had the same problem with:

    - FreeRTOS v9
    - GCC-7

    I can confirm that setting the BASEPRI works, for anyone interested here is a stripped variant of how I did it (assuming default priority of CRYPTOCELL_IRQn = 0):

    NVIC_EnableIRQ(CRYPTOCELL_IRQn);
    NRF_CRYPTOCELL->ENABLE = 1;
    
    SaSi_LibInit();
    
    /* First read the current basepri value */
    uint32_t prevBasepri = __get_BASEPRI();
    
    /* Mask (disable) all interrupts with priority greater or equal to 1 */
    __set_BASEPRI( 1 << ( 8 - __NVIC_PRIO_BITS) );
    
    CRYS_RndInit(&state, &buf);
    
    /* Restore the previous basepri */
    __set_BASEPRI(prevBasepri);

    Thanks!

Reply
  • Hi, nice work finding the problem and workaround(s).

    I had the same problem with:

    - FreeRTOS v9
    - GCC-7

    I can confirm that setting the BASEPRI works, for anyone interested here is a stripped variant of how I did it (assuming default priority of CRYPTOCELL_IRQn = 0):

    NVIC_EnableIRQ(CRYPTOCELL_IRQn);
    NRF_CRYPTOCELL->ENABLE = 1;
    
    SaSi_LibInit();
    
    /* First read the current basepri value */
    uint32_t prevBasepri = __get_BASEPRI();
    
    /* Mask (disable) all interrupts with priority greater or equal to 1 */
    __set_BASEPRI( 1 << ( 8 - __NVIC_PRIO_BITS) );
    
    CRYS_RndInit(&state, &buf);
    
    /* Restore the previous basepri */
    __set_BASEPRI(prevBasepri);

    Thanks!

Children
No Data
Related