APPROTECT and verify with nrfjprog

Hi

On the nRF52840-QIAA-R there should be implemented the APPROTECT according to this guide:

https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/working-with-the-nrf52-series-improved-approtect

Informational Notice (IN) - Vulnerability of the nRF52 series.

I implemented now the suggested code on top of main:

void AppProtection(void)
{
#ifdef ENABLE_APPROTECT
	if ((NRF_UICR->APPROTECT & UICR_APPROTECT_PALL_Msk) !=
		(UICR_APPROTECT_PALL_Enabled << UICR_APPROTECT_PALL_Pos)) {
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

        NRF_UICR->APPROTECT = ((NRF_UICR->APPROTECT & ~((uint32_t)UICR_APPROTECT_PALL_Msk)) |
		    (UICR_APPROTECT_PALL_Enabled << UICR_APPROTECT_PALL_Pos));

        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NVIC_SystemReset();
   	}
#else
	if ((NRF_UICR->APPROTECT & UICR_APPROTECT_PALL_Msk) !=
		(UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos)) {

        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

        NRF_UICR->APPROTECT = ((NRF_UICR->APPROTECT & ~((uint32_t)UICR_APPROTECT_PALL_Msk)) |
		    (UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos));

        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NVIC_SystemReset();
	}
#endif
}

This is working, but the problem is that the verify in production programming is not working anymore. Is there an option to verify the chip before? Because after a program the chip is getting restarted and read out protection is active which makes verify impossible. Is there a solution to verify with nrfjprog or use nrfjprog to program without starting the code on the nRF52?

nrfjprog --program %HEX_FILE% --verify --log

Parents Reply Children
  • Hi Priyanaka

    With the UIR flags its possible and working like expected.

    The logic is the following: Bootloader has its own UICR (index 1), application has its own UICR (index 0).

    If the index is empty, the bootloader and app is writing the predefined value to this index. Next restart (Reset, Power Reset) the code is checking this value and is writing the AppProtection Flag following by a reset. This logic is needed to ensure that the fisrt time the AppProtect is not activated, second time yes. 

    The if is preventing that this is happening at every reset, it will happen only once:

    void AppProtection(void)
    {
    #ifdef ENABLE_APPROTECT
        if (!is_customer_magic_set())
        {
            NRF_LOG_DEBUG("Customer Magic is not active");
            uicr_write_customer_magic();
        }
        else
        {
            NRF_LOG_DEBUG("Enable AppProtection");
            if ((NRF_UICR->APPROTECT & UICR_APPROTECT_PALL_Msk) !=
        		(UICR_APPROTECT_PALL_Enabled << UICR_APPROTECT_PALL_Pos)) 
            {
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
                NRF_UICR->APPROTECT = ((NRF_UICR->APPROTECT & ~((uint32_t)UICR_APPROTECT_PALL_Msk)) |
                    (UICR_APPROTECT_PALL_Enabled << UICR_APPROTECT_PALL_Pos));
    
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
    
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
                NVIC_SystemReset();
            }
    #else
        	if ((NRF_UICR->APPROTECT & UICR_APPROTECT_PALL_Msk) !=
        		(UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos))
            {
    
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
                NRF_UICR->APPROTECT = ((NRF_UICR->APPROTECT & ~((uint32_t)UICR_APPROTECT_PALL_Msk)) |
        		    (UICR_APPROTECT_PALL_HwDisabled << UICR_APPROTECT_PALL_Pos));
    
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
    
                NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
                while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
                NVIC_SystemReset();
        	}
    #endif
        }
    }

    Thank you for your help and if there is any issue or problem in the code please let me know

  • Hi,

    This looks like a good approach and the code snippet also looks nice. Slight smile

    Regards,

    Priyanka

Related