Security - IP Protection
I was wondering about securing firmware on the Pycom devices and have these following questions. Assuming the flash encryption is enabled and secure boot is enabled:
- When the device is connected to the REPL console via the COM port and the 'download files' command is given, will the downloaded files be encrypted or unencrypted?
- If you create frozen modules that is included in the FW build, is there a way via the REPL console and python builtins to inspect what classes,methods and variables are defined in these modules or even worse, get the body/code of a method? (assuming you have a main.py that references some frozen modules and start to drill down these modules)
- Assuming that frozen modules on encrypted flash is the most secure option, what is the limitation on code size (WiPy 3.0) since when doing OTA, the flash is burnt to the other 'previous' section. Basically the flash must be divided into two to achieve this alternating OTA feature.
- Is there any other CLI that can read/retrieve/download frozen modules?
@catalin Don't forget to lock the JTAG interface (if possible).
There is a fuse to disable JTAG (JTAG_DISABLE). Furthermore, unless you build a firmware with DEBUG enabled, the JTAG IO pins are re-initialised as inputs with pull-down enabled during micropython startup.
@inverseeffect The standard ESP32 has no built-in flash. It is all external SPI flash. However, there is a variant which has 2 MB Flash embedded (ESP32-D2WD), but that chip is not used for Pycom devices.
@catalin That will be great, or even just password protection on all interfaces or the ability for the user (the developer) to have more control on what happens when safe boot is executed.
Can you explain what flash sections are encrypted when flash encryption is enabled? Meaning the ESP32 onboard/builtin flash and/or the external SPI flash.
Never mind I found it here: http://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html
@catalin Don't forget to lock the JTAG interface (if possible).
catalin last edited by catalin
This is an interesting discussion. We could add your conclusions to our future development list.
We were looking into a couple of things to increase security:
- encrypted serial REPL (disabling UART clear text and telnet)
- encrypted FTP (disabling clear FTP)
<later edit:> The Flash Encryption and Secure Boot features have the role to protect ESP32 firmware. Now, furthermore, the micropython scripts are indeed not really .
@robert-hh I like this approach. I am use to baremetal micro controllers where read out protection is enabled and the only way is to erase the flash to reprogram the micro controller. (I just don't want to baremetal C anymore :), especially string handling and networking ) I can't see why the ESP32 should be any different except for the external SPI flash, but that is why the flash encryption feature exists.
@inverseeffect It should be possible to disable safeboot in secure mode. A fallback for recovery would then erasing the whole flash.
@inverseeffect The ESP32 is in no way a secure processor. It is simply not built for that purpose. If you need one, look at the secure processors of Maxim, TI and Freescale. Besides that, you get some low level obstacles with the ESP32. It is like all other properties of the ESP32 (I'm not talkling about the pycom integration). Many features for a low price, all built on a mediocre quality level.
I c. That is quite a vulnerability. Would you say that if we can get the REPL on the COM port password protected that the Pycom devices should be secure enough?
The last thing I want is to roll out devices and a few months/years I read in the media that 'my super product' has been hacked and is being used to gain acces to user,s WiFi etc.
@inverseeffect The main entrance is REPL, as you told. The encryption of the flash prevents access from "out of band" tools like esptools.py or direct probing of the flash chip, but once you can load or execute own code, your are "in". So running external code is to be prevented. A CRC is not a protection, because it does not rely on a secret.
Booting into safe boot prevent loading of main.py and boot.py and gives access to REPL. At least, i do not see in the sources where this is prevented. Then, any code can be pasted & executed. Functions like ustruct.bytes_at(addr, len) allow direct access to flash memory, which can be read & dumped, I assume it is unencrypted. That includes the area of frozen bytecode and the internal file system.
Hi, thanks fore the reply.
Regarding this question:
When the device is connected to the REPL console via the COM port and the 'download files' command is given, will the downloaded files be encrypted or unencrypted?
I was referring to the Pymkr plugin for Atom/VS code. Will these files, when downloaded be encrypted or unencrypted?
So would you agree with the following statement:
To make the Pycom module secure, the best method is to use secure boot + flash encryption and to use frozen bytecode modules for any source code you want to protect and disable the REPL COM port (since it is not password protected) during run time.
There is one backdoor still and that is:
Someone can still take the device and load their own boot.py and main.py when booting into safe mode. They can then try importing the frozen bytecode modules (from main.py) to get access to the 'protected' source code.
I guess one way to combat this is to let one of the frozen bytecode modules do a CRC32 checksum of main.py and boot.py when it is imported by main.py and if missmatched, reboot or even erase the file system.
My main concerns are:
- Wifi password
- Any client certificates
All the above can be encrypted and saved to files as long as there is no way to get to the encryption key
catalin last edited by
If, by download files you mean, esptool.py read_flash command, you will obtain the encrypted flash content.
If you create frozen modules that is included in the FW build, is there a way via the REPL console and python builtins to inspect what classes,methods and variables are defined in these modules or even worse, get the body/code of a method? (assuming you have a main.py that references some frozen modules and start to drill down these modules)
I know you can search a certain module name:
- in globals().keys()
- using something like
try: import hidden_module except:
Assuming that frozen modules on encrypted flash is the most secure option, what is the limitation on code size (WiPy 3.0) since when doing OTA, the flash is burnt to the other 'previous' section. Basically the flash must be divided into two to achieve this alternating OTA feature.
The frozen modules can have bytecode up to ~200KB, in the current firmware release. If more features will be added, they will eat-up flash memory. In the same time, we could increase OTA flash slots.
Is there any other CLI that can read/retrieve/download frozen modules?
I am not aware of a method of reading frozen modules.
robert-hh last edited by robert-hh
@inverseeffect As far as I understand, the encryption is transparent to the running code. That means, that you can always create a Python script, e.g. via REPL, that dumps the memory, at least most of it. However, the memory does not contain clear code. The machine code of the Python engine consists of xtensa assembler code, and is open source anyhow. Frozen bytecode of Python scripts are bytecode, not Python source. Still it contains the names of the modules, symbols an data in clear.
I do not know whether the file system is encrypted separately. Otherwise this content will be in clear in a dump.