Protecting your code



  • So, after a long time of testing and finally our own hardware design, we want to protect the code in the GPy so it can not be just stolen by the first Chinese company with a computer -sorry for the sarcasm. Does anyone have a good idea of how to protect the code of the device, so we can be somewhat safe in starting to sell these units?



  • @Don-iot
    Be aware of revision of the chip as some are still not safe even when you "turn on protection"

    https://www.espressif.com/en/news/Security_Advisory_Concerning_Fault_Injection_and_eFuse_Protections



  • @jcaron and @robert-hh thanks a lot for your insights. Great ideas and I think we have a few ideas moving forward!



  • @Don-iot I don't know if you can easily embed random files (i.e. something other than a frozen python file) in a firmware.

    You can try to include the data in the firmware:

    • Create a python file that contains that data (e.g. as strings), and as @robert-hh says, build one firmware version for each device with the relevant file.
    • Or check if there's a way to include other files in the firmware, and that the rest is the same.

    However that means that every time you update the firmware, you need to generate a version for each device. An alternative would be that the initial firmware actually write the data to the filesystem on first run.

    I think a better alternative is to have a standard firmware, but then provision each device. There are many ways to do that, including:

    • Use standard FTP to upload the files after flashing.
    • Include a provisioning mode in the firmware, which will run the first time (i.e. when the files are not yet present on the filesystem), and somehow receive the relevant data over the serial port. So you would flash, then wait for the provisioning system to start, and send the data. You of course need some integrity checks, retries, etc.
    • You can probably use the same methods Pymakr uses to transfer files over the serial port, but I have no idea if those are documented. IIRC it's just sending Python commands to the REPL or something similar?
    • Ditto, but have the initial provisioning code retrieve the device-specific data from a server (e.g. over HTTP). Each device must have a unique identifier (e.g. MAC address) which will have the server return the right data. This of course requires the device to somehow be connected to a network.
    • Another option could be to use the esptool to flash a custom filesystem image for each, but that seems like a lot of work when there are probably simpler alternatives.

    There are probably tons of combinations and alternatives, they depend a lot on the type of device, the environment, and more, but I hope this gives you a few ideas.



  • @Don-iot If this varying data is to be embedded into the firmware, you have to create an unique firmware for each of them. Since only a few frozen scripts are change, that build is rather fast, consisting of mpy-cross for the changed files, a single c-compile and link phase. The latter is the slowest. Uploading the firmware to the target will take longer than this custom build step, so you could to that on the fly.



  • @jcaron thanks for assistance, we have a working solution we think, now it is time to start the flashing of devices to test. Do you by any chance have an idea what would be the best approach for some files that are dynamic between devices. I mean the firmware is sort of the same from device to device, but we use TLS-encrypted MQTT and therefore the certificates are unique to the device. Also we have a json file that also differs between each device. What do you believe would be best practice here?



  • @jcaron Thanks a lot, I will ask the team to have a look!



  • @jcaron Yep, confirmed that python files in frozen which have a - in the filename will break the build. Rename them and you should be fine.



  • @jcaron Ah, could they be the names of the files maybe? Try renaming them to use _ instead of - (though you'll probably need to fix imports as well).



  • @Don-iot Can you edit your post and add ``` on a line before and after the log, so the formatting is kept?

    I think the ^ must point to the - in lte-version, am I correct?

    Identifiers in C can't include a -, only _. Those identifiers are probably somehow (incorrectly) derived from Python identifiers. Do you have anything matching those names in your Python code?



  • @Don-iot Never seen such errors. Please check the build tools settings and especially the compiler version, the setting of PATH and IDF_PATH, and eventually the mpy-cross version. Although the latter should be fine. It is important to precisely follow the instructions for the build environment set-up.



  • @robert-hh Thanks again for the tip, we have tried this now and have a problem intepreting the error codes, any idea what this seems to be?

    MPY frozen/LTE/sqnscodec.py
    GEN build/GPY/release/frozen_mpy.c
    CC build/GPY/release/frozen_mpy.c
    build/GPY/release/frozen_mpy.c:21944:35: error: expected '=', ',', ';', 'asm' or 'attribute' before '-' token
    STATIC const byte fun_data_lib_lte-version-retreive__lt_module_gt_[86] = {
    ^
    build/GPY/release/frozen_mpy.c:21982:44: error: expected '=', ',', ';', 'asm' or 'attribute' before '-' token
    STATIC const mp_obj_str_t const_obj_lib_lte-version-retreive__lt_module_gt__0 = {{&mp_type_str}, 42504, 41, (const byte
    ^
    build/GPY/release/frozen_mpy.c:21983:44: error: expected '=', ',', ';', 'asm' or 'attribute' before '-' token
    STATIC const mp_obj_str_t const_obj_lib_lte-version-retreive__lt_module_gt__1 = {{&mp_type_str}, 17683, 28, (const byte
    ^
    


  • @robert-hh Thanks, exactly what I was looking for!



  • @Don-iot Pycom devices support device encryption. see. https://docs.pycom.io/advance/encryption/#app


Log in to reply
 

Pycom on Twitter