In my setup i have a RT1176 with an MCUboot bootloader starting a Zephyrbased application.
For testing i moved some functions and constants to an AES-encrypted area and sat up and enabled the OTFAD device.
This works in debugging, my encrypted code is executed and the constants can be read with gdb. But if i call a function from the unencrypted area i.e. printk or want to pass back a char buffer to some unencrypted caller, i only receive gibberish or even a hard fault of the OS.
Is there any documentation about how to work with encrypted and unencrypted areas?
Thanks for any suggestions or help!
BR Mathias
Hi, thanks for your reply.
Sorry for the delay, I was out of office the last 2 weeks...
What i've tried:
otfad_encryption_config_t createOTFADContext()
{
otfad_encryption_config_t contextConfig;
contextConfig.AESdecryption = true;
contextConfig.contextIndex = kOTFAD_Context_0;
contextConfig.counter[0]=0;
contextConfig.counter[1]=0;
contextConfig.startAddr = 0x30040000;
contextConfig.endAddr = 0x30050000;
//union key myKey;
//strcpy("testkey_87654321", myKey.str);
for(int i=0; i<4; i++)
{
//contextConfig.key[i] = myKey.asInt[i];
contextConfig.key[i]=0;
}
contextConfig.readOnly = false;
contextConfig.valid = true;
return contextConfig;
}
void initOTFAD()
{
otfad_config_t config;
OTFAD_GetDefaultConfig(&config);
config.enableOTFAD = true;
config.flexspiBaseAddr = FLEXSPI1;
OTFAD_Init(OTFAD1, &config);
otfad_encryption_config_t enccontext = createOTFADContext();
OTFAD_SetEncryptionConfig(OTFAD1, &enccontext);
}
I organized this part to the address 0x30040000 via linker script:
#include "someTests.h"
#include <string.h>
__attribute__((section(".encrypted")))
const char someTests::someData[] = "This is top secret information and therefore encrypted";
void someTests::printSecretStuff(char* buffer)
{
strncpy(buffer, someTests::someData, 127);
return;
}
I have encrypted the memory region between 0x30040000 and 0x30050000 using the spsdk provided by nxp:
import os
os.chdir(os.environ['HOME']+ '/playground')
from spsdk.utils.crypto.otfad import KeyBlob
keybytes = bytes.fromhex("00000000000000000000000000000000")
counterbytes = bytes.fromhex("0000000000000000")
blob = KeyBlob(0x30040000, 0x30050000, keybytes, counterbytes, key_flags=0x3)
encrypted = blob.encrypt_image(0x30040000, toEncrypt, False)
encryptedArea = open("encrypted-area.bin", "wb")
encryptedArea.write(encrypted)
encryptedArea.close()
Then from the unencrypted part I call parts in the encrypted area:
initOTFAD();
printk("reached call of the encrypted data\n");
printk("printed via printk, direct accessing encrypted area:\n");
k_msleep(1000);
printk("%s\n", someTests::someData);
k_msleep(1000);
char buffer[128];
printk("printed via printk using strcpy of someData:\n");
strcpy(buffer, someTests::someData);
printk("%s\n", buffer);
strcpy(buffer, "");
printk("printed via function in the encrypted area:\n");
asm volatile ("dsb 0xf":::"memory");
asm volatile ("isb 0xf":::"memory");
someTests::printSecretStuff(buffer);
printk("%s\n", buffer);
What was surprising, the debugger reads someTests::someData correct (I can read the string in clear text), but printing doesn't work (gibberish output). When I reach the encrypted space, I can step through the code. but as soon as I reach a call to some unencrypted function, I get kernel panic or bus errors.
If this is not the way it's intended to be used, what is the right way?
Thanks for your help!
BR Mathias Landolt
Can you share detailed OTFAD region configuration info with me? OTFAD can support up to three regions.
You cannot call function from the unencrypted area. where is the unencrypted area? maybe we can create one unit test project for your case.