nRF5340 w/ 'Crypto: RNG', true or pseudo random numbers?

I am working w/ the nRF5340DK, and the project mentioned here (NCS v2.5.0, nrf/samples/crypto/rng). I was able to build/flash the project.

I wanted to verify whether the random numbers generated are pseudo random or true random. It appears to be true random (I get different numbers when I reset the board), but I wanted to double check.

What parameters, hardware, etc. would change whether it's pseudo or true? For example, does enabling/disabling something in KConfig, switching the hardware to nRF52840, etc. affect the result?

Parents
  • Hello,

    Yes, the RNG crypto sample uses the CC312 as the entropy source. In this sample, the psa_generate_random() function wraps around nrf_cc3xx_platform_ctr_drbg_get()

    /** @brief Function to get PRNG data using ctr_drbg
     *
     * @note  If the context is NULL the function uses an internal context.
     *
     * @details This function calculates random numbers using PRNG seeded by TRNG as
     *          defined in <em>NIST SP 800-90A: Recommendation for Random Number
     *          Generation Using Deterministic Random Bit Generators</em>. The
     *          random numbers are generated using Arm CryptoCell cc3xx hardware
     *          acceleration.
     *
     * @note Before calling this api the context to must be initialized by calling
     *       @ref nrf_cc3xx_platform_ctr_drbg_init.
     *
     * @note This API is only usable if @ref nrf_cc3xx_platform_init was run
     *       prior to calling it.
     *
     * @param[in,out]   context     Pointer to structure holding the ctr_drbg context.
     * @param[in]       buffer      Pointer to buffer to hold PRNG data.
     * @param[in]       length      Length of PRNG to get.
     * @param[out]      olen        Length reported out.
     *
     * @return 0 on success, otherwise a non-zero failure  according to the API
     *         mbedtls_ctr_drbg_random.
     */
    int nrf_cc3xx_platform_ctr_drbg_get(
        nrf_cc3xx_platform_ctr_drbg_context_t * const context,
        uint8_t *buffer,
        size_t length,
        size_t* olen);

    If you are unsure whether it is enabled in your application, you can check if the generated configuration file (if building without TF-M: build/zephyr/.config) contains CONFIG_ENTROPY_CC3XX=y. Another approach is to single-step through the code with a debugger.

    Best regards,

    Vidar

  • (OP replying) I can confirm seeing that it uses the CC312 when building for nRF5340...But I'm more interested in building nRF5340 Non Secure (using TrustedZone and such). However, it seems to use something else for the RNG and I cannot seem to pinpoint which function, entropy source, etc. is being called. Could I get some help identifying what's different when using Non Secure, and whether the numbers generated in Non Secure are pseudo or true random?

    • I tried inspecting the .config output file (for non-secure) and noticed the following settings that seem possibly relevant:
      • CONFIG_ENTROPY_PSA_CRYPTO_RNG=y
      • CONFIG_OBERON_BACKEND=y
      • CONFIG_MBEDTLS_HMAC_DRBG_C=y
    • When I single-step w/ a debugger, the call stack only goes as far as:
      • tfm_ns_interface_dispatch()
        • this is located in the NCS v2.5.0, zephyr/modules/trusted-firmware-m/interface/interface.c
      •  psa_call()
        • this is located in ./build/tfm/install/interface/src/tfm_psa_ns_api.c
      • psa_generate_random()
      • produce_rng_data()
      • main()
  • The difference when building for the *_ns target is that the crypto services are implemented in the TF-M firmware image, separating them from the app running in the Non-Secure Processing Environment. So the code will branch to the TF-M code running in the secure processing environment after tfm_ns_interface_dispatch(). I should have mentioned this in my initial answer, but following the code flow from the psa_generate_random() call to nrf_cc3xx_platform_ctr_drbg_get() is more challenging when using TF-M for several reasons. For instance, psa_generate_random() does not wrap around the crypto driver, instead it calls the psa_call() function to request RNG data from TF-M via the Non-Secure Callable Interface. The stacks are also seperated. 

    If you have debug symbols loaded for the TF-M image (this happens automatically when using our VS Code extension for debugging), you can place a breakpoint at the nrf_cc3xx_platform_ctr_drbg_get() call in nrf/subsys/nrf_security/src/psa_crypto_driver_wrappers.c to confirm that it is called.

Reply
  • The difference when building for the *_ns target is that the crypto services are implemented in the TF-M firmware image, separating them from the app running in the Non-Secure Processing Environment. So the code will branch to the TF-M code running in the secure processing environment after tfm_ns_interface_dispatch(). I should have mentioned this in my initial answer, but following the code flow from the psa_generate_random() call to nrf_cc3xx_platform_ctr_drbg_get() is more challenging when using TF-M for several reasons. For instance, psa_generate_random() does not wrap around the crypto driver, instead it calls the psa_call() function to request RNG data from TF-M via the Non-Secure Callable Interface. The stacks are also seperated. 

    If you have debug symbols loaded for the TF-M image (this happens automatically when using our VS Code extension for debugging), you can place a breakpoint at the nrf_cc3xx_platform_ctr_drbg_get() call in nrf/subsys/nrf_security/src/psa_crypto_driver_wrappers.c to confirm that it is called.

Children
Related