Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory space that remains unaffected on reset on ESP32 #4856

Open
hetvishah08 opened this issue Jun 18, 2019 · 11 comments

Comments

@hetvishah08
Copy link

commented Jun 18, 2019

Is there any way to store some variables which doesn't get affected on Reset?
I saw this memory partition named as NVS in Arduino ESP32 and ESP-IDF. This might work for me but I guess it hasn't been implemented on Micropython yet.
Any other way to store variables that remain unchanged on reset?
I want to store password credentials after acquiring once into memory space that is unaffected by reset.

@jimmo

This comment has been minimized.

Copy link
Contributor

commented Jun 18, 2019

Many MicroPython ports (including ESP32) provide a filesystem backed by flash. You can read and write files using the standard Python file APIs (e.g. open()). You might want to use the ujson to encode your data, or sometimes it's just simpler to write it out as a Python file (e.g. config.py) that you can import directly (import config / config.MY_VARIABLE). (If you've used WebREPL, this is how it stores its config).

You can find more info about this in the MicroPython Forum.

@hetvishah08

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

As I mentioned earlier, I want to store passwords that shouldn't be accessible to anybody. By using your method I will be able to create a file on the system but it can be accessed via REPL, which I don't want for security reasons.
That's why I want a memory space where i can store the password once.

@jimmo

This comment has been minimized.

Copy link
Contributor

commented Jun 18, 2019

Does your MicroPython code needs to be able to access these passwords later? Whatever API exists to make this available means that if your code can access it, then so can the REPL (regardless of where they're stored).

One option would be to never provide this API to Python, and confine all access to this data a C module (i.e. the private data would never be accessible to a Python method). But this is starting to get very specific to a given application (e.g. let's say it's the auth keys for a remote server, it means the C code has to do the auth and connection). But if you were to go down this route, then you could certainly use NVS to implement it.

NVS in a sense works just like the MicroPython filesystem - it provides a convenient key/value API on top of spiflash.

@rolandvs

This comment has been minimized.

Copy link
Contributor

commented Jun 18, 2019

Probably the best thing is to add a secure element like the ATECC608 from Atmel/MCP via I2C...

@hetvishah08

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

@jimmo Yes it needs to access those passwords after reset or whenever called in main.py. I haved used ucryptolib as an alternate to encrypt data and make it difficult to understand even if accessed through REPL. But I was looking for a memory solution.
NVS could be a solution but it hasn't been implemented yet?

@hetvishah08

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

@rolandvs currently I'm looking for a software solution. I will look into it for future updates in the hardware.

@WayneKeenan

This comment has been minimized.

Copy link

commented Jun 18, 2019

This is how to persist data in RAM over a reset in C, so would still require MicroPython plumbing, but at least you know you can.

https://esp32.com/viewtopic.php?t=4931

@jimmo

This comment has been minimized.

Copy link
Contributor

commented Jun 18, 2019

@jimmo Yes it needs to access those passwords after reset or whenever called in main.py. I haved used ucryptolib as an alternate to encrypt data and make it difficult to understand even if accessed through REPL. But I was looking for a memory solution.
NVS could be a solution but it hasn't been implemented yet?

I don't see how NVS solves your problem though. It's just another "filesystem" backed by the same flash. If your main.py can call a method like nvs.get("key"), then so can the REPL. You could use ucryptolib, but now you need somewhere to store your crypto keys, so you end up with the same problem. You just can't have secret data in your Python code.

However, there's one possible way you could address this while still only writing Python - that is to build a frozen module that contains:

  • your keys that you're using with ucryptolib
  • any code that needs to work with the secret data

As long as your frozen module doesn't have a method to access the key directly, but rather a connect() or do_thing_with_secret_data(), then it's much less trivial for someone accessing the REPL. (i.e. this is basically a way of doing what I suggested earlier but in Python instead of C).

This means that if someone can access the bytecode of your frozen module from the REPL then there's still a way in. The obvious way to do this is via machine.mem8. I'm not aware of a simpler way to do this, but I haven't looked in detail. But you can at least remove support for machine.mem8 from your firmware.

Note that someone can still physically connect to the flash chip and dump its contents. So flash encryption is important too.

This is how to persist data in RAM over a reset in C, so would still require MicroPython plumbing, but at least you know you can.

https://esp32.com/viewtopic.php?t=4931

This is neat, but I would imagine @hetvishah08 wants this data to be persisted across power cycles? And ultimately it has the same limitation as using NVS -- if a Python API existed for it, then anyone (main.py, the REPL, etc) can access it.

Probably the best thing is to add a secure element like the ATECC608 from Atmel/MCP via I2C...

@rolandvs I'm not super familiar with the details of secure elements, but I don't see a way this addresses the "need to be able to access this from main.py but not the REPL" problem. Generally my understanding was that you still require some sort of non-persisted key (e.g. interactive, or challenge-response) in order to interact with the secure element.

@WayneKeenan

This comment has been minimized.

Copy link

commented Jun 18, 2019

And ultimately it has the same limitation as using NVS -- if a Python API existed for it, then anyone (main.py, the REPL, etc) can access it.

Not necessarily, It could be a write only call from MicroPython such that the custom C module that provided that write API call could read it and use it after reset.

Although this is sounding all very hacky and prone to leaking in other ways, I can think of a couple...

@hetvishah08

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

However, there's one possible way you could address this while still only writing Python - that is to build a frozen module that contains:

  • your keys that you're using with ucryptolib
  • any code that needs to work with the secret data

Thank you for your help @jimmo . I have already made a different module to encrypt and decrypt the password and other credentials. I will add this module into frozen modules and call it in main.py.

As long as your frozen module doesn't have a method to access the key directly, but rather a connect() or do_thing_with_secret_data(), then it's much less trivial for someone accessing the REPL. (i.e. this is basically a way of doing what I suggested earlier but in Python instead of C).

This means that if someone can access the bytecode of your frozen module from the REPL then there's still a way in. The obvious way to do this is via machine.mem8. I'm not aware of a simpler way to do this, but I haven't looked in detail. But you can at least remove support for machine.mem8 from your firmware.

I don't know about machine.mem8. I'll look into it

Note that someone can still physically connect to the flash chip and dump its contents. So flash encryption is important too.

I just want to know whether Flash Encryption has been implemented yet? Also I would like to know about Secure boot.

@hetvishah08

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

Thank you for your help @WayneKeenan. My concern is to retain data at any reset.

@dpgeorge dpgeorge added the port-esp32 label Jun 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.