[Ovmsdev] Request For Comment: Protection of Sensitive Information on the Vehicle Module
mark at webb-johnson.net
Thu Aug 3 11:53:23 HKT 2017
I’m seeking comments/feedback/suggestions for the protection of sensitive information on the vehicle module for OVMS v3.
Firstly, here is the background document from Espressif regarding native ESP-32 flash encryption facilities, along with a short summary:
Flash encryption keys are normally randomly generated and stored in efuses that are write-only and protected so they cannot be read via normal means.
The chip transparently encrypts everything on flash when the facility is first enabled.
The chip transparently decrypts everything coming from flash, to the program running on the system.
There is a limitation that serial flashing (factory/developer image) can only happen three times with this system. However, OTA updates are unaffected by this limit.
Once the flash is encrypted, it is secure from tampering. But, you can always just upload another program to it (via OTA, or serial flash) and run that. Then, that program has full access to the decrypted flash. To get around that vulnerability, Secure Boot should always be used in combination with flash encryption:
A public key is stored in a write-once eFuse.
A matching private key is used to sign programs to be downloaded to the system.
The bootloader verifies the keys and current signature of program in flash, and will only execute correctly signed code.
Bottom line is that if an attacker has physical access to the device, then only a combination of flash encryption and secure boot can protect the contents of the flash. At that point, a microscope and chip etching is needed.
However, that is completely incompatible with open source development. Only the manufacturer (us, Open Vehicles, in this case) can sign programs to be loaded onto the device. It is also a PITA for developers (due to the limit of 3 flashes for factory/developer serially flashed images).
Our requirement is to protect sensitive information on the device. Things like wifi passwords, etc. The ESP32 provides us the flash encryption + secure boot option, as well as various storage areas we can take advantage of (RAM, NVM key-value store in flash, SPIFFS file system, eFuses). Assuming we aren’t going to use flash encryption + secure boot, and assuming we can compromise to limited protection from those with physical access to the device, what can we do?
I have created a stub config API:
void RegisterParam(std::string name, std::string title, bool writable=true, bool readable=true);
void DeregisterParam(std::string name);
void SetParamValue(std::string param, std::string instance, std::string value);
std::string GetParamValue(std::string param, std::string instance);
The config store is based on Param+Instance=Value. So, for example, we can have a parameter for wifi parameters, an instance of the wifi SSID, and the value being the password, etc. Each param can also be tagged as writable and/or readable by the end-user (the system itself must of course have full read/write access).
The question is how to implement that store in as secure a way as possible? OVMS v2 provided no protection - a serial console directly connected had access to everything.
One compromise suggestion I have is:
On boot, check NVM for an encryption key. If it doesn’t exist, randomly create it and store in NVM. That key is now per-device.
(Note that I am trying to find out if we can store that key in eFuse rather than NVM, and protect the eFuse from external serial reading, but still have access to it from running program - that would be slightly more elegant and a make things a little harder for an attacker, but I don’t know if it is possible)
Store the config values in flash SPIFFS filesystem, and encrypt them with the encryption key.
Both the above can be done within the config system, with no external access.
Have the commands to read/write config honour the readable/writeable flags and enforce the protection at the command level.
If we did that, someone with physical access to the device could either (a) upload their own code to read and print the configs, or (b) extract the flash contents, find the NVM key, and decrypt stuff themselves. Pretty much no protection for an educated smart hacker with time. We’re open source so this is trivial.
Protection against remote access to these protected configs would be better. So long as our command processor is not exploitable, or there is some other unknown remote exploit affecting us, we’re pretty secure.
Note that a suggested variant of this would be to store the key externally to the device and to have to enter it manually whenever the device is powered on (but before network access). Storing the key in ram would make it slightly more secure to external access, but would be more troublesome for the end-user to have to get a laptop out to plug it in and enter the key.
One other comment is that even if WE don’t enable flash encryption and secure boot, there is nothing stopping an educated end-user doing that. He would need to arrange to sign his own updates (and not use ours).
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the OvmsDev