Security

Posted on
Page
of 2
Prev
/ 2
  • Please can you try entering the following code on the left-hand side of the IDE and trying again?

    var f = require("Flash");
    for (var i=119;i>=115;i--) f.erasePage(i*4096);
    

    It's just a hunch, but it's possible that the bonding data got corrupted somehow - that will clear it out along with any saved code.

    Also, do you have any other devices you can try connecting with? I've tried multiple times here and I can't reproduce it - and without some way to get it to crash on my end I'm not sure how I can go about fixing it.

    Does anyone else have this problem?

  • Hi @Gordon,

    I applied your suggestion. On the first try I have same problem as before, while on the second and third try the Puck was reset, 3LEDs were on for a second, and was not able to connect to the Puck except remove and put the battery. I am using latest Linux Mint with Web IDE. Just a note to my workflow:
    1) Connect to the Puck, upload the code and disconnect.
    2) Connect with the Phone to test the uploaded functionality.
    3) Try to connect to the Puck, but this is not possible unless I close the browser, switch off the bluetooth, switch on the bluetooth and open the browser.

    Hope that could help somehow.

    Thank you.

  • Hi @Gordon,

    There is a progress!

    All previous tests were using "nRF Connect" on Android 4.4.2. Today I tried with Android 5.1.1 and happily everything worked as expected, i.e. Puck disconnect all connections to the device.

    Then I did a stress test to the Puck, pressing connect button once disconnected around 40-50 times, and finally the Puck was reset.

    Hope that helps.

  • Thanks! That's really helpful! Explains why I couldn't get anything working on my Android 6 (I think?) device. I'll just have to see if I can find an older Android device with BLE to test with.

    But you're saying you still got a reset after 40-50 connection attempts using a newer Android phone?

  • Hi @Gordon,

    Yes, up to 40-50th retry the Phone was disconnected, but after that Puck gives up and reset itself.

    Thank you!

  • Turns out it's not trivial to test this. Bluetooth LE support was only added in Android 4.3, so my old Android 4.0 phone won't do it!

    However as you suggest, by trying to connect loads of times I can eventually trigger this - and I have now fixed the issue you were having. It was actually an error in Nordic's connection negotiation library - it looks like it it doesn't like it if you disconnect at just the right time during the connection.

    A build with the fix in should soon be available at:

    http://www.espruino.com/binaries/travis/­10d203a64892263b7c9ac95758b291fd7166080c­

  • Hi @Gordon,

    The fix is working as expected.

    Thank you.

  • Hi,

    Do you think that following approaches are good for production:

    1) Provide password and decrease the transfer speed

    E.on('init', function() {
      E.setPassword("Password");
      E.lockConsole();
      NRF.setLowPowerConnection(true);
    });
    

    All possible password combinations based on this https://math.stackexchange.com/questions­/2103361/derive-an-algorithm-for-computi­ng-the-number-of-restricted-passwords-fo­r-the-gen#2103361
    combined with the low response speed, practically makes the Puck unbreakable ?

    2) Protect your functions with password ?

    function someFunction(pwd, parameters) {
      if (pwd!='FunctionPassword') {
        NRF.disconnect();
      }
      // process the request
    }
    

    Thank you.

  • Do you absolutely need access to the UART on the device? If not I'd suggest turning it off completely for production (with NRF.setServices). That would be the absolute safest option.

    You could then turn it on only if the button is pressed in a specific pattern?

    But if those don't work then yes, the first option would be fine (I don't think the second is a good idea). It would be possible (with a massive amount of difficulty) to solder debug wires onto the device, reverse engineer it, and get the password out - but even I'd struggle with that, and I made it :) It's almost certainly easier to reverse engineer the app!

    Another thing to note is that by default the transmissions over BLE are not encrypted, so could be spied on. To work around this, you could make your app request Bluetooth LE 'bonding' be performed (which starts encryption) and then only send the password after that has happened.

    But again, it's very unlikely that would ever be a problem depending on your device. By enabling the password you're already substantially more secure than the majority of Bluetooth LE devices.

  • Hi @Gordon,

    Thank you for your advises!

    • Suppose the code is saved and the "Password" in 1) is lost, how could the Puck be flashed for a new code to be saved ?

    • Is it possible two Pucks to be bonded, if so could you give an example ?

    Thank you!

  • That's fine - if you apply the battery with the button held down (normal firmware update process) you can totally update the firmware even with the password set - however you can't read the memory back that way, so it's still relatively safe with the password.

    You can request bonding with something like this (startBonding) - however you need a very recent build as it only got added a week or so ago (it's not in 1v92). The travis builds have it in: http://www.espruino.com/binaries/travis/­master/

    var gatt;
    NRF.requestDevice({ filters: [{ name: 'Puck.js abcd' }] }).then(function(device) {
      console.log("found device");
      return device.gatt.connect();
    }).then(function(g) {
      gatt = g;
      console.log("connected");
      return gatt.startBonding();
    }).then(function() {
      console.log("bonded");
      gatt.disconnect();
    }).catch(function(e) {
      console.log("ERROR",e);
    });
    

    Having said that, it seems to work but isn't properly tested yet

  • Hi @Gordon,

    I think that a workable security scenario could be:

    1) Provide a password and decrease transfer speed on start up - this will protect the uploaded code from being viewed or modified. Here we will save a mapping between the Puck MAC address and the generated password.

    2) Once the client receive the Puck with the uploaded code it should create "bonded" connection from the Gateway(Android phone, for example which will gather all the data), and will set IP for access where onConnect will disconnect any different than the provided IP connections and will automatically generate a password for all getter characteristics to protect them from other unauthorized third parties.

    3) If the Puck requires a new code, the most secure way of doing that is to send to the client physically a Puck with the new code, secured in same way as described above in 1), where it has a mapping between IP and password only for the Pucks that have to be updated. The new Puck should initiate "bonded" connection one by one with all Pucks that have to be updated and will "self-propagate the code".

    What do you think ?

    Thank you.

  • I'm not quite sure I understand - by IP you mean the MAC address? But it sounds pretty secure to me.

    Also - nothing stops you from just issuing them a new firmware for their device that they can update with nRF connect/similar?

  • Hi @Gordon,

    IP is the MAC address of the device that can connect to the Puck.

    Concerning the process of update through firmware, how secure is it ? Once the package is on the party which is doing the update could it be decoded and source revealed, if we talk about the "bin" and "dat" file in the firmware I think not, but please confirm.

    If not, should I build from https://github.com/espruino/Espruino with my code added in it ? Should I write the new firmware functions in "C" or I can pass my existing my Javascript code and Espurino translate it to C and include it into the distribution package ?

    Thank you.

  • Hi @Gordon,

    Thank you for the bonding functionality, I tested it with latest build and it seems to work! How can I execute https://www.espruino.com/Puck.js+BLE+UAR­T with bonding ? In general, accessing the primaryService and characteristics should happen after bonding right ? Do you have any docs for it ?

    Thank you.

  • Once the package is on the party which is doing the update could it be decoded and source revealed

    Assuming you upload normally (and not with 'save on send') the JS code will be fragmented over the memory area, and then compressed. With a huge amount of difficulty, it could be decoded (but even I'd struggle). The best solution would be to turn on minification when you upload your code to Espruino, which would make the uploaded code almost unreadable even if it could be deciphered.

    At that point it's going to be much more difficult to work anything out from your code than it would be if someone disassembled compiled C code, so I really wouldn't worry about it.

    You could translate your JS code to C (or for simple functions you can use http://www.espruino.com/Compilation), but I wouldn't advise it. Personally I'd say the difficulty of reverse engineering minified JS after it's been encoded into datastructures and compressed with heatshrink makes it about as difficult as you're going to get.

  • For bonding, I believe that if you follow the steps to bond first, then disconnect, any subsequent connections will also be bonded - so just running the code posted above, and then the BLE UART code, would be fine.

  • Hi @Gordon,

    Is there a way the source code hex to be protected from reading ?

    Why do I need this ? Suppose you have a device which code is protected from reading, but its hex is not, then third party could use this hex to program new devices which will work no matter there is no understanding why.

    Thank you!

  • You could add some code to your software that checks getSerial() - which is a hard-coded chip serial number. That way the same hex file won't work if used on different devices.

  • Hi @Gordon,

    Could you explain more about "DFU_PRIVATE_KEY=targets/nrf5x_dfu/dfu_p­rivate_key.pem" specified during the build ?

    This file contains private and public key. My understanding is that the generated zip file used for DFU and initial firware upload will be signed with the private key but will contain only the public key. When the device needs a DFU update the uploaded zip file will be tried to be opened with the public key on the device. If the zip cannot be opened then it is signed with different private key, thus we can be sure that on the device can be uploaded only firmware singed with the appropriate private key right ?

    Thank you!

  • Nordic has lots of resources on this - it's their bootloader. For instance https://devzone.nordicsemi.com/b/blog/po­sts/getting-started-with-nordics-secure-­dfu-bootloader

    Espruino's private key is in the repository which means that anyone can create a signed over the air update for it - defeating the point somewhat.

    However in order to do an update you need physical access to the device, and if you have physical access you could just reflash it via the SWD pins. It's one reason I have resisted allowing you to enter DFU mode without pressing BTN during boot - because that really would be a security issue.

    If you're trying to understand this so that you can create secure update zip files for your own devices then I'm happy to do some consultancy work to help out.

    Also, you'd asked before about adding microphones. I recently got the MP34DB02 working with the nRF52 for the Nordic Thingy - it's a fully digital mic, so if you hadn't already got something sorted out it could be quite interesting as it's basically a single-chip solution.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Security

Posted by Avatar for user71324 @user71324

Actions