How to determine if running on locked Teensy or if encrypted

shawn

Well-known member
I could have sworn @PaulStoffregen posted a reply to someone describing how to do this, but I can’t seem to find it. If anyone can point me to it (if I didn’t dream it), that would be wonderful.

My question has two parts:
1. What’s the best way to determine if the currently running program is running on a locked Teensy?
2. Is there a way to determine if the program is running from an encrypted EHEX? (Given the fact that a Teensy doesn’t need to be permanently locked to run an EHEX.)
 
To know the upload would have to be monitored in Teensy Loader / Verbose Info - or a custom sketch used and uploaded. One of the security sketches might do that without harming anything?

During the beta test for that I combined some of those features to post SerMon details - though not updated after final release IIRC, so not posting the link untried
 
Not sure if you are asking, to know external from your sketch or for your sketch to know if it is running on a locked Teensy.

As Defragser mentioned you can look at the loader log to see if it uploaded using the .ehex file instead to .hex
But this does not necessarily say that the teensy is locked:

At run time, we have a few sketches that check to see if you are running with encryption enabled:

Something like:
Code:
 // lets check to see if the T4 is setup for security first
#if defined(__IMXRT1062__)
  if ((IOMUXC_GPR_GPR11 & 0x100) == 0x100) {
      Serial.printf("Security Enabled\n");
...
But again, this simply says we are running with encryption (first couple of parts of the puzzle)

Looking at the Lock program, I see after he sets the board in lock mode, he verifies it with:
Code:
        if ((HW_OCOTP_CFG5 & 0x04C00002) == 0x04C00002) {
          Serial.println("Success: Secure mode set");

That is what I would try...
 
I’m looking for determining this information at runtime. I’ll explore those register values set by those security sketches.

I’m still convinced there’s a post I read once that Paul posted showing some reasonably robust ways of doing this.
 
Quick update:
Code:
uint8_t blink_count = 0;
void setup() {
  while (!Serial && millis() < 3000)
    ;
  Serial.printf("Check Teensy 4.x security\n");
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  if ((IOMUXC_GPR_GPR11 & 0x100) == 0x100) {
    Serial.printf("Security Enabled\n");
    blink_count = 1;
    if ((HW_OCOTP_CFG5 & 0x04C00002) == 0x04C00002) {
      Serial.println("Appears to be locked");
      blink_count = 2;
    }
  }
}

void loop () {
  digitalWriteFast(13, HIGH);
  delay(1000);
  for (uint8_t i = 0; i < blink_count; i++) {
    digitalWriteFast(13, LOW);
    delay(250);
    digitalWriteFast(13, HIGH);
    delay(250);
  }
  digitalWriteFast(13, LOW);
  delay(1000);  
}

Ran this on two T4.1s. One locked and one not (not is not lockable)... Did not try the intermediate state.

For the locked one:
Code:
Check Teensy 4.x security
Security Enabled
Appears to be locked
And it does a screwy long blink double blink:

For standard Tt.1
It just outputs: Check Teensy 4.x security

And it gives a standard blink
 
Did a quick test on this beta sketch: github.com/Defragster/T4LockBeta/tree/main/T4MemInfoKitchen

It has refs from the PJRC security sketches - maybe not all the latest - but works as follows.

Locked T_4.1 - can ONLY run EHex:
Code:
Verify secure code is running properly

Pass: Bus Encryption Engine is active
Pass: Encryption region starts at proper address
Pass: Program data is entirely within encrypted region
Pass: title_function() is within encrypted region
Pass: title_text[] is within encrypted region
Pass: csf as expected
NOTE: hab_version == 0x40307
NOTE: hab_status == 0xF0
Secure mode IS set :: Fuses == 0x4C8B01A

All Tests Passed.  :-)

T_4.1 recent can run eHex, but not lockable - running eHex:
Code:
Verify secure code is running properly

Pass: Bus Encryption Engine is active
Pass: Encryption region starts at proper address
Pass: Program data is entirely within encrypted region
Pass: title_function() is within encrypted region
Pass: title_text[] is within encrypted region
Pass: csf as expected
NOTE: hab_version == 0x40307
NOTE: hab_status == 0xF0
Secure mode NOT SET :: Fuses == 0x8B018

 1 Tests failed.  :-(12167540 ENC ns:

T_4.1 running .HEX:
Code:
Verify secure code is running properly

Fail: Bus Encryption Engine is not active
Fail: Encryption region starts at wrong address
Fail: Program data is not within encrypted region
Fail: title_function() is not in encrypted region
Fail: title_text[] is not in encrypted region
Fail: csf not as expected
NOTE: hab_version == 0x40307
NOTE: hab_status NOT == 0xF0
Secure mode NOT SET :: Fuses == 0x8B018

 8 Tests failed.  :-(12167540 nor ns:
 
Last edited:
Looks like this program does not reserve the HAB memory. The hab_status check is probably unreliable.

See the LockSecureMode sketch from Tools > Teensy 4 Security (currently only in Arduino 1.8.x, so far Arduino 2.0.x doesn't support adding tools). Look for the comment "// do not delete this line!"
 
Looks like this program does not reserve the HAB memory. The hab_status check is probably unreliable.

See the LockSecureMode sketch from Tools > Teensy 4 Security (currently only in Arduino 1.8.x, so far Arduino 2.0.x doesn't support adding tools). Look for the comment "// do not delete this line!"

Cool if that is the only issue. It released fast after the last changes and didn't go over one last time.
 
If you add the HAB memory reserve, I'm pretty sure you'll see a different (and correct) hab_status result for a .HEX file. It definitely should not be 0xF0 (no errors detected), since HEX files have an all-zeros CSF. You're getting the 0xF0 result because the USB buffers overwrote the HAB log where the error info was stored.
 
About the original question, the fuse bits are the best way to check if security is locked.

Theoretically, it is possible to lock security without using encryption (which prevents the hardware from running other people's programs without concealing your own code), but the tools published by PJRC don't support that. If you want to check encryption just in case, the test whether the bus encryption engine is active and if your program data is entirely within the encrypted region is the right thing to verify.

But if you know the code was built using PJRC's tools (and not with NXP's CST or MCUX utilities) then just checking the fuse bits should be enough.
 
If you add the HAB memory reserve, I'm pretty sure you'll see a different (and correct) hab_status result for a .HEX file. It definitely should not be 0xF0 (no errors detected), since HEX files have an all-zeros CSF. You're getting the 0xF0 result because the USB buffers overwrote the HAB log where the error info was stored.

Correct - Github and p#8 updated
 
Back
Top