Setting flash security byte

Status
Not open for further replies.

hyperdyne

Active member
Is there a way to enable the Flash security byte (FSEC) so downloading code (easily) from a teensy is disabled? I've done some research and the MK20dx128.s file has the FSEC register setting, but I am unable to find this file in the arduino directories. I did find Mk20dx128.c file in teensy/avr/cores/teensy3 dir, but it wasnt apparent if I could change something in that one file. Anybody done this before?
 
I think you want to start with:
https://forum.pjrc.com/threads/24365-Protecting-Firmware-Code
There have been some changes in the space but I believe for T3.x the download of code is disabled by the bootloader (lives onboard the second CPU on the T3s) so the only way to change unset it is to load code yourself to change it (and the bootloader wipes all code during load so you can't just sneak in a bit flip into existing code). Do be careful playing in those registers since it's possible to brick a Teensy if you set the 'prevent code changes' bits without someway in your program to unset them.
 
Yes, to set the security feature on Teensy 3.2, you need to edit mk20dx128.c. But this process has never really been documented. Until now, just for you! ;)

https://github.com/PaulStoffregen/cores/commit/aeff63583d89adbee6d10db5f0ef019570e4f69f

Pay attention to that advice in the comment. Normally with Teensy, if you accidentally press the Program button, you can recover by just power cycling. Once you lock security, any press of the button forces full chip erase.
 
Ok so I tried setting the fsec bit using Paul's new mk file. But after programming the teensy 3.2 the Teensy audio adapter shuts down. The serial monitor is still running in arduino ide showing that code is running. Any ideas?
 
Ok I did some more testing. I was able to compile the new mk file and load it up. Afterwards it says the teensy loader cannot force a reboot. But the program runs and I get serial output and the audio board is now working.

Question: Am I supposed to be able to reprogram the board? It appears I can, and the docs dont really say much on this. Basically I can press the program button and it doesnt erase the chip, it programs it again. I am just wondering if this is the expected behavior. I dont have any of the flash regions locked, but wasnt sure if FSEC cuts off reprogramming.
 
hyperdyne - read the code comment linked in post #3. I'm not sure if I'm not reading it right, something unexpected is happening, or the post #7 isn't explaining what is really happening.
According to that: the program button should allow the IDE and TeensyDuino to flash NEW code. If it doesn't get new code after a button press it will just start with existing code unchanged when repowered? It can only reprogram if sent new code.

It may be interesting to use this feature someday - but for now you are the guinea pig on a new change. Perhaps try jumping between a fast and slow blink with serial output to track the running code and detail what you find?
 
Ok I did some more testing. I was able to compile the new mk file and load it up. Afterwards it says the teensy loader cannot force a reboot. But the program runs and I get serial output and the audio board is now working.

Question: Am I supposed to be able to reprogram the board? It appears I can, and the docs dont really say much on this.

Here is what the docs actually say:

Code:
// Flash Security Setting. On Teensy 3.2, you can lock the MK20 chip to prevent
// anyone from reading your code. The bootloader will be unable to respond to
// auto-reboot requests from Arduino. Pressing the program button will cause a
// full chip erase, because the bootloader chip is locked out.  Normally, erase
// occurs when uploading begins, so if you press the Program button accidentally,
// simply power cycling will run your program again.  When security is locked,
// any Program button press causes immediate full erase.  To set the security
// lock, change this to 0xDC.  Teensy 3.0 and 3.1 do not support security lock.

I believe your description "the teensy loader cannot force a reboot" are the same as "The bootloader will be unable to respond to auto-reboot requests from Arduino".

Basically I can press the program button and it doesnt erase the chip, it programs it again.

Actually, it does erase the chip when you press the button. Then moments later the upload programs the blank chip with your code.

Normally, the erase happens when Teensy Loader sends the first piece of data. This may seem like a minor unimportant detail, and indeed is makes no practical difference for when you're just uploading programs. Either way, the chip gets erased shortly before your new code is written.

To see why this is important, you must test differently. Upload a program that does something you can easily observe. The LED blink example is perfectly fine. Close Arduino and Teensy Loader. Watch the Teensy to make sure it's running the program. Then press the button "accidentally". Imagine Teensy is running from a power supply or a computer without Arduino and your code. Because this was an accidental button press, unplug and reconnect Teensy to the USB cable. If the chip was locked, you'll see no blinking when you plug the cable back in, because your Teensy is now blank due to the button press. If the chip wasn't locked, Teensy will run the previously programmed code when you plug the cable back in, because the button press does not normally erase Teensy's memory.

I tried to explain this in the docs, but perhaps it's not clear? Please try this with your Teensy, and imagine the scenario where you've installed Teensy into some application and an end user it able to accidentally press the button.

When you're using FSEC to lock the chip, you need to be careful about the button. It must not be pressed accidentally (when you do not wish to reprogram), and it must be pressed to initiate the upload.

I am just wondering if this is the expected behavior.

Everything you've described is the expected behavior.

but wasnt sure if FSEC cuts off reprogramming.

No, changing FSEC this way does not prevent reprogramming. But you must press the button.

How could I edit the docs to make this clearer?
 
Paul,

Thank you very much for your detailed response. That does indeed makes sense, and I will perform the test you outlined.

What I got hung up on was the reprogramming of the flash after the button press. From the below I read it as the bootloader would be locked out ad infinitum, thus not being able to reprogram. This is not how it operates and it was an oversight on my end.




Here is what the docs actually say:

Code:
// Flash Security Setting. On Teensy 3.2, you can lock the MK20 chip to prevent
// anyone from reading your code. The bootloader will be unable to respond to
// auto-reboot requests from Arduino. Pressing the program button will cause a
// full chip erase, because the bootloader chip is locked out.  Normally, erase
// occurs when uploading begins, so if you press the Program button accidentally,
// simply power cycling will run your program again.  When security is locked,
// any Program button press causes immediate full erase.  To set the security
// lock, change this to 0xDC.  Teensy 3.0 and 3.1 do not support security lock.

I believe your description "the teensy loader cannot force a reboot" are the same as "The bootloader will be unable to respond to auto-reboot requests from Arduino".



Actually, it does erase the chip when you press the button. Then moments later the upload programs the blank chip with your code.

Normally, the erase happens when Teensy Loader sends the first piece of data. This may seem like a minor unimportant detail, and indeed is makes no practical difference for when you're just uploading programs. Either way, the chip gets erased shortly before your new code is written.

To see why this is important, you must test differently. Upload a program that does something you can easily observe. The LED blink example is perfectly fine. Close Arduino and Teensy Loader. Watch the Teensy to make sure it's running the program. Then press the button "accidentally". Imagine Teensy is running from a power supply or a computer without Arduino and your code. Because this was an accidental button press, unplug and reconnect Teensy to the USB cable. If the chip was locked, you'll see no blinking when you plug the cable back in, because your Teensy is now blank due to the button press. If the chip wasn't locked, Teensy will run the previously programmed code when you plug the cable back in, because the button press does not normally erase Teensy's memory.

I tried to explain this in the docs, but perhaps it's not clear? Please try this with your Teensy, and imagine the scenario where you've installed Teensy into some application and an end user it able to accidentally press the button.

When you're using FSEC to lock the chip, you need to be careful about the button. It must not be pressed accidentally (when you do not wish to reprogram), and it must be pressed to initiate the upload.



Everything you've described is the expected behavior.



No, changing FSEC this way does not prevent reprogramming. But you must press the button.

How could I edit the docs to make this clearer?
 
I've reworded the documentation to explicitly mention you can reprogram. Hopefully this will be clearer?

https://github.com/PaulStoffregen/cores/commit/50c805926fb871b795b62cdb5d4efad767dde825

Hi there,
Just to make things even easier, I just submitted a pull request here that makes it a compiler #define.

https://github.com/PaulStoffregen/cores/pull/199

Also, by editing the boards.txt file, as specified in the comment to this pull request, you get a nice UI switch between secure and insecure modes.

-Caleb
 
I revamp this thread to ask confirmation about the intended worklow for setting the security byte on the flash RAM of my Teensy 3.2.

As I understand, the typical steps would be the following:

  1. Go to the directory ./hardware/teensy/avr/cores/teensy3/ and open the file mk20dx128.c with a text editor.
  2. Find the line #define FSEC 0xDE and modify it to #define FSEC 0xDC .
  3. Save the file.
  4. Start the Arduino IDE, compile and upload your sketch on Teensy 3.2.
  5. Note: Teensy will not automatically reboot after the upload has been completed.
  6. Turn off and on the power a couple of time to make your new uploaded sketch running
  7. If you don't need to upload other Tensys with the security byte set, then go back again to the file mk20dx128.c and restore the original #define instruction. Then save the file.

Is what above correct?

However, there is something still not clear to me.
Let's suppose that, after a couple of months, I discover a bug in my sketch. Do I need to set again the security byte to 0xDC before uploading the fixed version of the sketch? Or I can do this even with FSEC set to its original value (0xDE)?
 
I revamp this thread to ask confirmation about the intended worklow for setting the security byte on the flash RAM of my Teensy 3.2.

As I understand, the typical steps would be the following:

...
Is what above correct?

However, there is something still not clear to me.
Let's suppose that, after a couple of months, I discover a bug in my sketch. Do I need to set again the security byte to 0xDC before uploading the fixed version of the sketch? Or I can do this even with FSEC set to its original value (0xDE)?

From my reading and understanding the list of items is correct.

For desired security setting the CORES file indicated must be changed. Any upload with the altered byte will have the altered behavior. Any upload without that byte set will assume the normal behavior.

The change goes with the sketch uploaded, it does not make a permanent change in Teensy behavior.

If this is something at hand for your use - you can quickly confirm and leave notes on the findings.

#1: Build a blink sketch with default settings. Locate and save and rename the HEX file appropriately. One way to do this is 'Export' sketch will put it into the Sketch Folder IIRC
#2: Build a blink sketch with Altered setting - and a UNIQUE blink rate - or print to SerMon. Locate and save and rename the HEX file appropriately.

Open Teensy Loader and document the behavior AFTER upload - on the upload following the sketch #1 or #2 above.

It should be that any upload after #1 is normal Teensy style and any upload after #2 will require a button press for upload.
 
However, there is something still not clear to me.
Let's suppose that, after a couple of months, I discover a bug in my sketch. Do I need to set again the security byte to 0xDC before uploading the fixed version of the sketch? Or I can do this even with FSEC set to its original value (0xDE)?

Yes, you need to again edit the security byte to 0xDC before uploading.

Of course, you can upload using the default setting. But if you do that, the hardware will no longer have the security lock set.

(....or to be technically correct to the point of pedantic - when security is set, pressing the button fully wipes the chip and unlocks the security setting. Until you upload again, the chip is actually unlocked, but also blank. Uploading with 0xDC re-locks the security setting.)



5: Note: Teensy will not automatically reboot after the upload has been completed.
....
Is what above correct?

#5 isn't quite right. By itself, not a big deal if Teensy does reboot to running your program when you believed it couldn't.

But perhaps #5 is a sign of misunderstanding the main caveat of having the security lock set? Indeed, once the lock is set (which happens during that first reboot after the upload) then your PC can't cause the upload to happen automatically. You will need to press the button. But that's not the main issue...

The important point is *when* your code is erased. Normally, with an unlocked chip, erase happens when Teensy Loader begins transmitting data. Simply pressing the button doesn't erase or change anything. If you press the button accidentally, you can just power cycle the board and your code will run again. With the normal unlocked way, the odds of getting your Teensy into a non-operational state are very slim, because the chip is erased and then programmed in a single operation which happen over the span of just a second or two.

With the code security lock set, full erase happens when you press the button. The huge consequence is even a brief momentary accidental touch of that button causes a full wipe of your program. If you power cycle the board without uploading a new copy of your program, it will not boot back up because the flash memory has been completely wiped clean. Because the chip erase happens as a different time than uploading, if you do things improperly there is a much greater chance your Teensy can end up blank.

If your board does end up blank, of course you can always just upload again. But if you're setting the security lock, presumably you will do something like give the programmed hardware to someone you don't trust. The pushbutton is essentially a "self destruct" button once the Teensy has left your hands, and whoever has it is unable to re-upload the code. You need to prevent the button from being accidentally pressed!

One other minor consequence is the full wipe also deletes any EEPROM data. The normal erase deletes your old program, but preserves the EEPROM storage.
 
Last edited:
Thanks Paul and defragster for the answers.

But perhaps #5 is a sign of misunderstanding the main caveat of having the security lock set?
Definitely it is.
Take in account that a lot of people (like me) come from previous experiences with Arduino. This can lead to some misunderstandings for the average monkey (again, like me! :D).
With a traditional Arduino you have just one button: the RESET button. On the other hand, on Teensy, that button is a "Program button", i.e. it is used to upload a new sketch into the flash memory. In the orthodox way, to run the new uploaded sketch, one has to power off-on Teensy.
I never touched the program-button, the Teensy-Loader is doing all for me, this has strengthened the wrong idea about the existence of the "reset-button".

So, now I think I understood some things:

1. the button on Teensy is for "preparing" the chip to receive a new sketch
2. when the security-byte is set, manually pressing the program-button becomes mandatory. It will erase the flash memory necessary to accommodate the new sketch.
3. when the security-byte is set, any accidental pressing of the button will erase the flash (and the EEPROM) memory.
4. when the security-byte is set, the new sketch will not run immediately after the upload, one has to manually power off-on Teensy
5. by uploading again a new sketch with the original security byte value (0xDE) everything works like normally

Is what above right?

if you're setting the security lock, presumably you will do something like give the programmed hardware to someone you don't trust. The pushbutton is essentially a "self destruct" button once the Teensy has left your hands, and whoever has it is unable to re-upload the code. You need to prevent the button from being accidentally pressed!
What?
Are you sure?
Even if the security byte is set, everybody having my Teensy in his hands can use it and upload a new sketch of his property. Or not??? I'm missing something?


once the lock is set (which happens during that first reboot after the upload) then your PC can't cause the upload to happen automatically. You will need to press the button. But that's not the main issue...
Well, for a lot of people that would be not an issue. For me it is a total no-go issue.
My circuit is completely flooded with a (special) resin. This makes impossible to press the button for re-programming the Teensy. So, no way for me to fix the software if I discover a bug.
This make the security-feature completely useless in my case. :(:(:(
 
Take in account that a lot of people (like me) come from previous experiences with Arduino. This can lead to some misunderstandings

Yes, but then also consider that even though the chips used on normal Arduino boards have similar security lock features in their hardware, Arduino doesn't normally offer any support for using the code security lock. So I'm not quite sure what sort of prior experience from Arduino could possibly apply in this case?


With a traditional Arduino you have just one button: the RESET button. On the other hand, on Teensy, that button is a "Program button", i.e. it is used to upload a new sketch into the flash memory. In the orthodox way, to run the new uploaded sketch, one has to power off-on Teensy.
I never touched the program-button, the Teensy-Loader is doing all for me, this has strengthened the wrong idea about the existence of the "reset-button".

Yes, this is one way Teensy differs from Arduino.

With regular Arduino, when the hardware boots up, it runs Arduino's bootloader. If no upload starts, after a brief timeout it runs your program. As a consequence, on all Arduino boards your program suffers a pretty substantial delay from powerup until the bootloader gives up waiting and jumps to your code.

Many Arduino boards have a dedicated USB-serial converter chip. No matter what goes wrong with your code, the USB-serial always works because it runs on a different chip.

With Teensy, your program is run immediately upon powerup. No bootloader runs first. The USB is also native, inside the same chip. There are plenty of things your code can do to sabotage the USB port. For both of these reasons, the button on Teensy is dedicated to entering bootloader mode.

Imagine what could happen if Teensy's button were only a Reset. You could upload a corrupted program which shuts off the USB port. Pressing the button would just re-run that program, leaving the USB port worthless! Then you'd be forever stuck. This is why the button is dedicated to entering Programming mode. It is meant to give you a way to always recover from uploading a bad program.


About your questions, mostly correct, expect this one.

4. when the security-byte is set, the new sketch will not run immediately after the upload, one has to manually power off-on Teensy

Power cycling is not needed in this case.

Technically, the security lock is *never* set during uploading. If the lock had been set, it gets unlocked during the memory wipe when you press the button. The security lock is not set when Teensy Loader detect your board and does the upload.


Even if the security byte is set, everybody having my Teensy in his hands can use it and upload a new sketch of his property. Or not??? I'm missing something?

Maybe you're misunderstanding the purpose of the security lock. The security lock's purpose is to prevent anyone from being able to read a copy of your code.

The security lock does not prevent other people from being able to program the chip. Once the chip is blank and unlocked, anyone can upload their own program.

The security lock prevents access to the chip's memory, so competitors who would clone your product are unable to obtain a copy of your code. That's why the process of unlocking the security requires a complete wipe of the chip's memory. It's designed to prevent cloners from stealing a copy of your code.


My circuit is completely flooded with a (special) resin. This makes impossible to press the button for re-programming the Teensy. So, no way for me to fix the software if I discover a bug.
This make the security-feature completely useless in my case.

The Program signal is available at a pad on the right hand side of the board. You could solder a wire to that pad and bring it outside, perhaps to a button or some other way you momentarily short it to GND.
 
If the lock had been set, it gets unlocked during the memory wipe when you press the button.
Pressing the button always unlock the lock? For this reason is necessary to force the complete erasure of the flash? To prevent malicious reading of the uploaded code, yes?


The security lock is not set when Teensy Loader detect your board and does the upload.
It happens at the first run of a sketch with the security byte set to 0xDC, yes?


Maybe you're misunderstanding the purpose of the security lock. The security lock's purpose is to prevent anyone from being able to read a copy of your code.
Yes, I understood that. I just misinterpreted the verb "re-upload" that you used. You meant "re-upload [the cloned program]". Now I got it.


The Program signal is available at a pad on the right hand side of the board. You could solder a wire to that pad and bring it outside, perhaps to a button or some other way you momentarily short it to GND.
Uh! That's an option. I will investigate about that.
 
Very interested in all the above, thanks for the info.
Am I right in thinking that connecting the program signal (from pad on right hand side of board) to a spare pin and supplying it with 3.3v via a resistor (plus possibly a capacitor ) would allow a re-program from an existing (and normally used for another purpose) external button? Perhaps the re-program would be initiated by a unique button-press sequence during the setup loop?

Or better still, can the re-program initiation be done purely in software?
 
Or better still, can the re-program initiation be done purely in software?
You're inspiring bad ideas in my mind... :D
What if I connect that pad to an output pin of Teensy itself? What happens with an instruction like "digitalWrite(LOW)" executed on that pin???
 
Ok I should have researched before posting my last question.

It appears that reprogram initialisation can be done in software:

_reboot_Teensyduino_();

I am guessing: if the security byte is set and the program button is inaccessible, calling the above command in my sketch should put the teensy into program mode ready for a new sketch upload. Will have to test this before deploying into the field.
 
Status
Not open for further replies.
Back
Top