Shop OBEX P1 Docs P2 Docs Learn Events
Has Anyone Been Working On A Code Protection Scheme For The P2? — Parallax Forums

Has Anyone Been Working On A Code Protection Scheme For The P2?

I am wondering what the options are and if anyone has been developing any code to help prevent code theft and duplication.
«1

Comments

  • On boards that include a network interface I use a 24AA02E48 ROM with a unique MAC address. I scramble the (main) code with that unique number. The bootloader reads the MAC ROM and unscrambles the rest of the code into RAM.

    Simply copying the code EEPROM won't run on another board with a different MAC. Of course, it's not hacker-safe. If somebody disassembles the bootloader he could replace the MAC variable with a constant and bypass the protection.

    But I think the best protection is that the P1 and P2 are not produced in China (as opposed to PICs, Atmels and others). So if they want to copy a propeller product they have to import it and pay customs duties and that is something they just don't want to.
  • RaymanRayman Posts: 13,918
    edited 2021-01-07 13:38
    It's the same as P1 as far as I know.

    The only sure way I know is to only have the code only in RAM and use batteries to keep it always on...

  • I use several ways from back in the day. The first is to use copy & paste to take your regular variables and constants like: MyMotor and make it as: $A52D in meaningless hex number Do this for every one of variables you have.

    The second is to pack the last bit of your memory with both your good working code and garbage code that really goes nowhere but will frustrate the reverse engineer guy into thinking it really does something (important).

    The third way is to insidiously make an output voltage go into an input pin to absolutely destroy the IC / at least make all the output results go crazy. Let your imagination go wild here. Hope this helps.
  • The flash memory chip has a unique ID that could be used in a similar manner to what @ManAtWork described -- but you'd have to include the ability to write to flash so that on first download the ID could be read, obfuscated, and stored in another section of the flash. I did something like this on the P1 using a 1-Wire sensor as the ID. The first run after download would read that ID, scramble it into a bunch of nonsense code and store it in the EE. If that EE was the copied and moved to another circuit with a different ID, this would be detected and the EE erased, bricking the device.

    As others have said many times, if somebody really wants your code and they have the resources, they'll get it.
  • Rayman wrote: »
    It's the same as P1 as far as I know.

    The only sure way I know is to only have the code only in RAM and use batteries to keep it always on...

    yes I think this is the best approach

    On P1 the lowest quiescent current was around 1uA. On the P2 we measured 34uA from memory.
  • jmgjmg Posts: 15,148
    idbruce wrote: »
    I am wondering what the options are and if anyone has been developing any code to help prevent code theft and duplication.

    It comes down to degree of effort.
    As mentioned above, a simple serial number prevents easy slavish copying or volume creepage.

    Flash memories sub 10c have 128 bit unique IDs, and many small MCUs (20~30c) have unique IDs. (eg The EFM8UB3 in P2D2 gives i2c access to the UB3 UID )

    If someone really wants to, they can capture the P2 bitstream, and disassemble the code the edit and reassemble, but if they have that skill set, they can develop (better?) P2 systems already ! ;)

    You can also disperse the security, eg with a small MCU to do some peripheral tasks, and then the attacker needs to crack that part as well.
  • First off, I thank everyone for their input.

    I have mentioned this in the past, but I will mention it again. Many years ago, I wrote some duplication prevention code for Windows programming that relied upon checking the Volume IDs. At that point in time, I believed it was fairly bulletproof, but the software never got off the ground, so I am unsure how it would have all worked out.

    However I do believe it would be beneficial for me to go back and review that code and see if any of it can be applied to some of the ideas that were expressed here.

    Thanks everyone :)
  • Another way to get at this problem is to basically ignore the code protect. Do something if you want. Unless it is the always on battery method, it can be cloned.

    But, part of the real value lies in the thing the P2 is controlling. Make part of that secret sauce something you make that is hard to make the same way.

    Even the copiers may come to you for it. Fine, charge em.
  • @potatohead
    But, part of the real value lies in the thing the P2 is controlling.

    In this particular instance, the firmware is the most important part, or at least that is the way I see it, since the mechanical aspect can be easily duplicated, and many are already in existence. As it pertains to mechanical design, there is nothing that can be added for any real benefit or uniqueness. It is the firmware that separates it from similar products.
  • evanhevanh Posts: 15,203
    If you're selling a good product, you'll get a good name. Word of mouth will keep you very busy.

  • potatoheadpotatohead Posts: 10,254
    edited 2021-01-08 06:18
    Sell them fast, spiff them for referrals. Make all you can in the new product window then. Good luck!

    Edit: Also differentiate on service, quality, ease of purchase, etc. All of those go a long way.
  • idbruce,

    A lot of places are quick to see you their magic widget but when you need help no one is available except if you want to buy something else.

    Great support such as what Parallax does will keep them coming back.
  • The P2D2 has the EFM8UB3 which can shut-down the P2 if I use a code-protection scheme. The UB3 has a 128-bit UUID and the P2 communicates with the UB3 over I2C. But the best protection is not to shut down the P2, just make it work for a while after reset and then unreliable if things aren't right.
  • cgraceycgracey Posts: 14,133
    edited 2021-01-08 12:26
    Someone asked me the other day if there was anything unique that could be gleaned from a P2 chip for code-security purposes. It made me think that the ADC calibration readings are unique, due to slight manufacturing-process inconsistencies. So, I made a Spin2 program to plot relative GIO-calibration readings from P0..P31. There is definitely uniqueness. I then got a heat gun to see how things changed and the relative differences only change slightly.

    Here is a picture of two different P2 chips' calibration values for GIO over room-temp to too-hot-to-touch:

    P2_Fingerprints.png

    Here is the program:
    _clkfreq = 20_000_000
    _pins    = 0 addpins 31
    _bits    = 14
    
    var v[32]
    
    PUB go() | i
    
      debug(`plot p title pos 100 100 size 536 320 backcolor white `dly(200))
      debug(`p set 268 304 green 4 text 14 3 'Relative GIO-calibration ADC readings of P0..P31)
    
      repeat i from 0 to 31
        debug(`p set `(20 + i * 16) 13 green 4 text 12 3 270 '`(i)')
        debug(`p grey 12 set `(20 + i * 16) 30 line `(20 + i * 16) 286 blue)
    
      'keep reading and plotting values as cold and heat are applied
      repeat
        measure(p_adc_gio)	'change to p_adc_vio for vio calibration
        repeat i from 0 to 31
          debug(`p set `(20 + i * 16, v[i] + 30) dot 4)
    
    PRI measure(mode) | i, min, max, x
    
      'take 10 sample sets for thermal stability (use 10th set)
      pinstart(_pins, mode | p_adc, _bits - 1, 0)
      repeat 10
        akpin(_pins)
        repeat until ina.[_pins]
        repeat i from 0 to 31
          v[i] := rdpin(_pins + i)
    
      'get min and max values
      min := $10000
      max := 0
      repeat i from 0 to 31
        x := v[i]
        if x > max
          max := x
        if x < min
          min := x
    
      'apply offset & scaling and rewrite sample values as 0..255
      repeat i from 0 to 31
        v[i] := (v[i] - min) * 255 / (max - min)
    

    There is definitely enough uniqueness to form an encryption key. I think it would be pretty conservative to generate a table of pin pairs which have at least a 1/4-full-range separation between them. The sign of their difference could reliably provide one bit of the key. There are also VIO readings you could use, along with readings from P32..P63. This is an internal ADC operation that has no bearing on what is connected to the actual pin, and it does not affect the pin.
    575 x 935 - 36K
  • cgraceycgracey Posts: 14,133
    edited 2021-01-11 18:56
    Here I plot GIO and VIO together for one chip. The GIO is blue and the VIO is red. Approximately same heat span as before:

    P2_Fingerprint_GIO_and_VIO.png

    The code:
    _clkfreq = 20_000_000
    _pins    = 0 addpins 31
    _bits    = 14
    
    var v[32]
    
    PUB go() | i
    
      debug(`plot p title pos 100 2000 size 536 320 backcolor white `dly(200))
      debug(`p set 268 304 green 4 text 14 3 'Relative GIO&VIO ADC readings of P0..P31)
    
      repeat i from 0 to 31
        debug(`p set `(20 + i * 16) 13 green 4 text 12 3 270 '`(i)')
        debug(`p grey 12 set `(20 + i * 16) 30 line `(20 + i * 16) 286)
    
      'keep reading and plotting values as cold and heat are applied
      repeat
        measure(p_adc_gio)	'measure and plot GIO readings
        repeat i from 0 to 31
          debug(`p set `(18 + i * 16, v[i] + 30) blue dot 4)
        measure(p_adc_vio)	'measure and plot VIO readings
        repeat i from 0 to 31
          debug(`p set `(22 + i * 16, v[i] + 30) red dot 4)
    
    PRI measure(mode) | i, min, max, x
    
      'take 10 sample sets for thermal stability (use 10th set)
      pinstart(_pins, mode | p_adc, _bits - 1, 0)
      repeat 10
        akpin(_pins)
        repeat until ina.[_pins]
        repeat i from 0 to 31
          v[i] := rdpin(_pins + i)
    
      'get min and max values
      min := $10000
      max := 0
      repeat i from 0 to 31
        x := v[i]
        if x > max
          max := x
        if x < min
          min := x
    
      'apply offset & scaling and rewrite sample values as 0..255
      repeat i from 0 to 31
        v[i] := (v[i] - min) * 255 / (max - min)
    
    573 x 378 - 14K
  • I think this is a good approach. I was trying to think of a way to use the same data as a key, but was thinking more along the lines of ranking the pins, then extracting a result from the ranking, but its still sensitive to small movements of pins within the ranking. Your sign idea is much better

  • RaymanRayman Posts: 13,918
    Looks sorta like a DNA test...
  • cgraceycgracey Posts: 14,133
    edited 2021-01-08 14:35
    I'm thinking about how to best exploit the differences, in order to glean the most bits, reliably.
  • YanomaniYanomani Posts: 1,524
    edited 2021-01-08 14:39
    These are very promising findings, indeed.

    Throwing another level of (yet unnoticed) determinism into the mix is now available to track-down "who is who", but it'll still need another secure and reliable (and also deterministic) peer, at the other side of any (serial?) comms link, in order to exchange some key parameter(s), so to keep an extended boot proccess going, after any initial (and, forcefully, "in the open") software upload (to the P2).

    Those proccess can nicelly leverage from the time it takes for the P2 to start answering back, and even doing any other "pre-agreeded" tasks, since extra-lenghtned routines, or even the start of any (many) other Cog(s) would affect these intervals, easeing the task for the other peer, in order to notice there's something weird going on.
  • BeanBean Posts: 8,129
    Chip, Nice work, keep at it.
    If you come up with a reliable "fingerprint" that is stable over all temperatures/ voltages I would be very interested in using it.

    Bean
  • So from the plot it looks like the worse case difference between min and max is about 10% of full range. So that would yield about 25 different values. Let's call it 16 so if gives us 4 bits. With 32 pins that would provide a 128-bit encryption key.

    However, it seems like there are a couple of issues. How can we get a consistent 4-bit value over the temperature range? Some, or maybe most of the pins will straddle an adjacent value. As an example, if we read a 4-bit value of 3, then at some other temperature it could be a 2 or maybe a 4.

    The other issue is that the boot program has to be un-encrypted. How do you protect from this being hacked?
  • VonSzarvasVonSzarvas Posts: 3,283
    edited 2021-01-08 19:34
    Here's two plots from two Edge modules to show the extent of change with temperature.

    Both started at room temp, then dropped to about -10C (freeze spray), then up to about 60C (hair dryer)
    683 x 447 - 36K
    684 x 447 - 36K
  • Cluso99Cluso99 Posts: 18,069
    This method also relies on the pins being free. Any tracking/connections will likely vary the result.
  • RaymanRayman Posts: 13,918
    @Bean mention voltage... Any chance this varies with core and logic voltages?

    Maybe it doesn't really matter as long as measured in final configuration?
  • RaymanRayman Posts: 13,918
    Does knowing that this technique was used to encode the program help somebody trying to hack it?
  • @Cluso99 when the measurements are being taken the pin mux is connecting the ADC to VIO and GIO, rather than the physical pin connection. So it shouldn't depend on whats connected to the pin

  • Cluso99Cluso99 Posts: 18,069
    Tubular wrote: »
    @Cluso99 when the measurements are being taken the pin mux is connecting the ADC to VIO and GIO, rather than the physical pin connection. So it shouldn't depend on whats connected to the pin
    Ok great. Didn’t think about this way.
  • YanomaniYanomani Posts: 1,524
    edited 2021-01-08 22:13
    @cgracey

    Starting on rev. C silicon, I believe smart pin mode %100010_OHHHLLL can also be useful, since it no longer connects the ADC to the adjacent pin, but would be able to capture the floating bias point of each one.

    Unless a varying operational temperature can severelly affect its sense range (or usefulness), perhaps adding those samples into the mix could turn the extraction of the extra bit(s) you are looking for, into a real possibility.

    Hope it helps.

    Henrique
  • jmgjmg Posts: 15,148
    Dave Hein wrote: »
    The other issue is that the boot program has to be un-encrypted. How do you protect from this being hacked?
    The fingerprint idea looks good for an ID generate, but you are right, the disassembler pathway still exists for a sufficiently skilled and determined copier.

  • jmgjmg Posts: 15,148
    Dave Hein wrote: »
    However, it seems like there are a couple of issues. How can we get a consistent 4-bit value over the temperature range? Some, or maybe most of the pins will straddle an adjacent value. As an example, if we read a 4-bit value of 3, then at some other temperature it could be a 2 or maybe a 4.
    It may be simpler to store the mid band of each print bar, and then check for excess deviation from that.
    That avoids boundary errors, but takes a bit more to store the band values.
    UIDs like this could be useful for larger systems and to pass to an overall security checker.

Sign In or Register to comment.