DeviceKey API usage on nrf52840 blocks deep sleep?

Hello all,

not sure if this is a bug or known behavior but when I am using the DeviceKey API on mBedOS 6 (I have tested 6.5, 6.7 and 6.11) on my nrf52850 I experience a block of the mbedOS deep sleep functionality of about 67% of the time even though the key was already created.

Does anyone has any idea why this happens or even has a solution? Here is my (simple) example for the test (don´t forget to add “platform.all-stats-enabled”: true to your target_overrides in mbed config):

/*Device Key generation test on mBedOS 6 */

#include "mbed.h"
#include "mbed_stats.h"
#include "DeviceKey.h"

DigitalOut led_green(LED1, 1);
DigitalOut led_red(LED2, 1);

// If key derivation fails hang 
void hang()
{
    printf("HARDFAULT, hanging\n");
    led_red = 0;
    while(true) {};
}

// Print an unsigned char buffer in hex format
void print_buffer(unsigned char *buf, size_t size)
{
    for (size_t i = 0; i < size; i++) {
        printf("%02X", buf[i]);
    }
}

// Create/print the device key and salt
int Device_Key_Gen() {
	
	int status = DeviceKey::get_instance().generate_root_of_trust();
	
	if(status == DEVICEKEY_SUCCESS) {
		//success
		printf("SUCCESS: Root of trust generated!\n");
	} else {
	   //error
	   printf("INFO: Root of trust not generated! Maybe already exists!\n");
	}

	DeviceKey &devkey = DeviceKey::get_instance();

	unsigned char derive_key1 [DEVICE_KEY_32BYTE];
	unsigned char salt1[] = "ch00se_s0m3_salt";		
	int ret = DEVICEKEY_SUCCESS;

    // 32byte key derivation
    ret = devkey.generate_derived_key(salt1, sizeof(salt1), derive_key1, DEVICE_KEY_32BYTE);
    if (DEVICEKEY_SUCCESS != ret) {
        printf("Error, derive key failed with error code %d \n", ret);
        return -1;
    }

	// print device key and salt
	printf("Device Key = ");
	print_buffer(derive_key1, DEVICE_KEY_32BYTE);
	printf("\n");
	printf("Salt for key derivation = %s\n", salt1); 
	
	return 0;
}

int main()
{	
	// start
	led_green = 1;
	led_red = 1;	
	
    printf("Device Key...");
	if (!Device_Key_Gen() == 0) {
		hang();
	}
	printf("OK\n");
	

	while (true) {
	
	//let the status led blink
        led_green = !led_green;
		ThisThread::sleep_for(100ms);
		led_green = 1;
		ThisThread::sleep_for(10s);
	
	//some mbed stats to check sleep status
 		mbed_stats_cpu_t stats;
		mbed_stats_cpu_get(&stats);
		printf("Uptime: %llu ", stats.uptime / 1000);
		printf("Sleep time: %llu ", stats.sleep_time / 1000);
		printf("Deep Sleep: %llu\n", stats.deep_sleep_time / 1000);	

    }
}

can you also post the logs ? What are the numbers?

You can enable sleep tracking, to find out what is locking the sleep and when. I am browsing the DeviceKey implementation and I can’t spot locking deep sleep there.

Hello Martin, thank you for your response. Sure, here are the logs for the above mentioned code. As you can see in 1, the device is only entering deep sleep for 3.5 (3528ms) seconds / 10 seconds. There is no information in the sleep tracing (see 3) about any process blocking the deep sleep. I was wondering if it might be somehow related to the TRNG keeping the CPU active? The key is generated properly and as far as I understand there should be no other processes running continuously afterwards no?

  1. Using DeviceKey API:
00> Device Key...INFO: Root of trust not generated! Maybe already exists!
00> Device Key = B0CE795XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00> Salt for key derivation = ch00se_s0m3_salt
00> OK
00> Uptime: 10129 Sleep time: 0 Deep Sleep: 3529
00> Uptime: 20229 Sleep time: 0 Deep Sleep: 7056
00> Uptime: 30329 Sleep time: 0 Deep Sleep: 10585
00> Uptime: 40429 Sleep time: 0 Deep Sleep: 14117
00> Uptime: 50529 Sleep time: 0 Deep Sleep: 17645
00> Uptime: 60629 Sleep time: 0 Deep Sleep: 21174
00> Uptime: 70729 Sleep time: 0 Deep Sleep: 24703
00> Uptime: 80829 Sleep time: 0 Deep Sleep: 28235
00> Uptime: 90929 Sleep time: 0 Deep Sleep: 31763
00> Uptime: 101029 Sleep time: 0 Deep Sleep: 35292
  1. Without DeviceKey API:
	/*
    printf("Device Key...");
	if (!Device_Key_Gen() == 0) {
		hang();
	}
	*/
	printf("OK\n");
00> OK
00> Uptime: 10100 Sleep time: 0 Deep Sleep: 10099
00> Uptime: 20200 Sleep time: 0 Deep Sleep: 20199
00> Uptime: 30300 Sleep time: 0 Deep Sleep: 30298
00> Uptime: 40400 Sleep time: 0 Deep Sleep: 40398
00> Uptime: 50500 Sleep time: 0 Deep Sleep: 50497
00> Uptime: 60600 Sleep time: 0 Deep Sleep: 60597
00> Uptime: 70700 Sleep time: 0 Deep Sleep: 70696
00> Uptime: 80800 Sleep time: 0 Deep Sleep: 80796
00> Uptime: 90900 Sleep time: 0 Deep Sleep: 90895
00> Uptime: 101000 Sleep time: 0 Deep Sleep: 100995
  1. Sleep Tracing results with DeviceKey API and -DMBED_SLEEP_TRACING_ENABLED:
00> Device Key...INFO: Root of trust not generated! Maybe already exists!
00> Device Key = B0CE795XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00> Salt for key derivation = ch00se_s0m3_salt
00> OK
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:
00> Sleep locks held:

Do you have any response on this? Should I add it as a bug on github?