cancel
Showing results for 
Search instead for 
Did you mean: 

RNG access after starting BLE stack

eleventen
Associate III

It looks as if the RNG is made unavailable to the M4 when the M0 has booted the BLE stack. This looks to be true because I can initialize and use the RNG before starting the BLE stack. Once I launch C2, the RNG registers read as zeros.

Is this a requirement of the BLE stack? We don't use any of the security features in BLE and it would be much more useful to have access to the RNG from the M4 instead of using the HCI interface. Is there a way to we can retain control of the RNG from the M4?

13 REPLIES 13
Remi QUINTIN
ST Employee

The use of the True Random Number Generator TRNG is protected with a Semaphore (Sem0).

Access to the TRNG is under Semaphore (Sem0) control which implicitly means the TRNG is used on the CM0+ side.

The CM0+ uses the RNG for the advertising phase to generate cryptographic keys.

So if an application running on the M4 core requires the TRNG, it must register to the waiting list for this semaphore waiting for an interrupt when this resource is released. Then the sequence below  is the generic one to use a shared resource.

Take Sem0

Use the True Random Number Generator (TRNG)

Release Sem0

Remi QUINTIN
ST Employee

Forgot to say that as soon as the CM0+ core is activated, it starts advertising and so preempts the TRNG for its own usage making it inaccessible for a while to the M4 core.

eleventen
Associate III

I found the following in the Cube samples. Is there documentation about what these semaphores protect, how they must be used, and guarantees that must be upheld. For example, how long could I wait for a semaphore lock? If there is a lock on RCC, what does it cover, e.g. everything in the peripheral? Is the protection enforcement mechanism documented?

   29 /* Index of the semaphore used to manage the entry Stop Mode procedure */
   30 #define CFG_HW_ENTRY_STOP_MODE_SEMID                            4
   31 
   32 /* Index of the semaphore used to access the RCC */
   33 #define CFG_HW_RCC_SEMID                                        3
   34 
   35 /* Index of the semaphore used to access the FLASH */
   36 #define CFG_HW_FLASH_SEMID                                      2
   37 
   38 /* Index of the semaphore used to access the PKA */
   39 #define CFG_HW_PKA_SEMID                                        1
   40 
   41 /* Index of the semaphore used to access the RNG */
   42 #define CFG_HW_RNG_SEMID                                        0

I think what your follow-up comment says is that the RNG is unavailable while the BLE is advertising. At least, that is what I'm seeing. Is this something we can get fixed? We do not use Bluetooth encryption, so there is no need for the WB to hold onto the RNG while advertising. I think that our only alternative would be to stop advertising if we need to run the RNG.

It would be much better for us to be able to use the RNG while BLE is advertising.,especially considering that some product use cases will *only* advertise because there will be no connections made. IOW, the device will only transmit information via advertising.

I think it is a little worse than you say. If I boot the C2, but don't initialize the BLE stack, the C2 holds the RNG lock. If I boot the C2, initialize the BLE stack and do everything except make the device advertise, the C2 holds the RNG lock. If I do everything up to and including setting the device to advertise, the C2 holds the RNG lock. If I connect to the application via Bluetooth, the C2 holds the RNG lock. IOW, the C2 doesn't seem to release the lock under any circumstances I can find.

There may be something else at play. As far as I can tell, as long as the C2 is booted, the RNG is locked and unavailable to the application on the M4. Can you share some test code that demonstrates gaining access to the RNG from the M4 when the C2 is running?

Remi QUINTIN
ST Employee

>the C2 doesn't seem to release the lock under any circumstances

This is unexpected. Both M4 and M0+ core should have access to the TRNG once they manage to get the semaphore.​

The CM0+ core uses the TRNG to generate a few random numbers and then can use it during the advertising phase. But it should be releases after this phase.

Can you show the SW code sequence you are using to get the semaphore and wait for it when it is not free?

eleventen
Associate III

Looking at the HSEM status when the HeartRate application runs, it seems as if the issue I'm seeing is really about configuration or setup. The HeartRate application does not hold the RNG lock once the application is running.

Is there anything you can share about the C2 code that would help be determine where I might be going wrong in my setup? Keep in mind that I'm not using CubeMX. I'm configuring the MBOX and IPCC with the same size parameters as the sample code.

Also, I can tell that my application is working because I'm able to advertise my BLE services and read/write characteristics.

So, what could be holding up the HSEM lock on the RNG?

Remi QUINTIN
ST Employee

​Hard to undesrtand!

I would recommend you to have a look at some simple example code located here:

STM32Cube_FW_WB_V1.3.0\Projects\P-NUCLEO-WB55.Nucleo\Examples\HSEM.

One example is describing How to enable, take then release a semaphore using 2 different Process.

eleventen
Associate III

It's not obvious how we could be seeing an issue with HSEM acquisition, per se. Our functions, shown, appear to have the correct behavior with respect to the peripheral. However, even though we can read some data from the RNG, eventually, the C2 holds the lock indefinitely.

    init = false;
 
    cblock = 0;
    crng = 0;
 
    while (crng < CRNG_LIM && cblock < 1000*1000) {
      if (HSEM::acquire (STM32::HSEM_ID_RNG)) {
        if (!init) {
          RCC::enable_per (RNG_PER);
          RNG_CR = RNG_CR_EN;
          init = true;
        }
 
        auto l = HSEM_nR (STM32::HSEM_ID_RNG);
        if (RNG_SR & RNG_SR_DRDY) {
          auto v = RNG_DR;
          ++crng;
          printf ("%08lx [%08lx]\n", v, l);
        }
        else
          ++cblock;
        HSEM::release (STM32::HSEM_ID_RNG);
      }
      else
        ++cblock;
    }

The acquire function:

 inline bool acquire (int id) {
    return HSEM_nRLR (id) == (HSEM_R_LOCKED
                              | owner (STM32::HSEM_COREID_CURRENT)); }
  inline void release (int id) {
    HSEM_nR (id) = owner (STM32::HSEM_COREID_CURRENT); }

This is what the Cube code calls the 1-step acquisition.

The output is OK the first time, but on the second invocation, the HSEM lock is never released by C2.

# tR
f488f11c [80000400]
49f2d612 [80000400]
...
6c63794f [80000400]
59b48971 [80000400]
8a2ef513 [80000400]
b5dcb6ee [80000400]
# 100 9035
daphne# tR
# 0 1000000
daphne# tR
# 0 1000000
...

The HSEM lock for the RNG shows the value 0x80000800 which indicates that the C2 is holding the lock. We also verified that the release function is working correctly.

If C2 is not booted, the output is more what we would expect, numbers ad infinitum.

# tR
12c419bb [80000400]
82500ffc [80000400]
8f5fc882 [80000400]
e4631e31 [80000400]
8aee6bea [80000400]
98bf1279 [80000400]
7b563370 [80000400]
...
efb59f38 [80000400]
69517345 [80000400]
# 100 27745