Locking/unlocking parts in source code with a key

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I’m trying to figure out a way to lock or unlock parts of source code on the AVR.

What want to achieve is to have only one hex file, but be able to lock or unlock some features (modules) with some kind of a key code, which would be given to the customer.
But I also want to be able to flash the firmware for updates, which the customer can do by himself.

Thus I thought of making some kind of a key or serial number which will be a unique number for each unit.

I thought about using a serial data flash chip, where you can block parts of memory to put a serial number, or even better use the write once only memory bytes that some serial data flash chips have.

Would that be secure enough, which kind of encryption could I use for that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Off the wall idea... Add an SD card interface to the AVR. Supply an SD to the customer with a single text file on it called "key.txt". Inside the AVR read this file - pass it through a hash algorithm (MD5, SHA, SHA256, whatever) and then compare the resultant "hash" with a list of expected results and enable the functionality based upon this.

Sure the customer can read key.txt but the key thing is that they don't know how to change it to produce the right hash value (which is a one-way process)

Cliff

PS Be warned things like MD5/SHA/SHA256 are mathematics intensive and will "cost" at least 10K of code space (I got SHA256 into an ARM bootloader in 11K in fact)

PPS obviously the text could be delivered on some other medium but SD is nice because you could simply email a key.txt to the customer, tell them to write it to the SD and then insert into the AVR - so they can easily have new features enabled when they have paid.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why don't you use onboard EEPROM for your "key" storage. The EEPROM could contain one or more bytes where bits are set to enable specific parts of your code in flash. If your code is written in a modular format (it will have to be), then when your code execution reaches a decision point on whether or not to execute a certain section, or feature, the appropriate EEPROM bit is checked to see if that feature is enabled. If not, that code section is skipped.

Ideally, the customer would update code and features through a bootloader. The customer's user interface into the bootloader in the product would be under your control. This is to prevent them from peeking around inside the product trying to enable features that they are not authorized to use.

When a request for an additional feature is received from a customer, an encypted keycode would be created and sent to the customer. The user interface would take care of decoding the keycode and creating the proper binary pattern to send to the product (stored in EEPROM) to enable the requested features.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm, could a real cryptographic hash like MD5/SHA/be substituted with something like CRC-32?

It does not matter what the hash is, as long as it is secret.. And knowing the hash list won't do any good if the hash method is unknown.

So I think CRC-32 could be easy too. Like with MD5, you just need to have the customer specific original data (passwords) from which the hashes are created to put those hash results in the code before compiling (or even after compiling to EEPROM or something) and to recreate the hashes you give the original data (passwords) to customer, right?

So in any case, even if customer knows the hashes are CRC-32 or MD5, and would know a hash value list, it would be long enough procedure to solve a string that would have the same hash, as it's not the hash that is sent to the micro. Besides the passwords might have some limitations in them that the customer does not know, so that at least or at most some amount of characters is required (fixed length bad?) etc.

Interesting ideas yes. But what if your customer has one of your boards, and another customer sends his EEPROM data or firmware file to the other? Or buys one board with all the features, and starts cloning the firmware and EEPROM information to make new boards with all the features? How do you prevent this?

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This "KEY" enabling is used in the cnc machine tool industry to allow customers to "expand" the capabilities of their machines.On my Haas machines all the features are there,all it takes is a sizable check and the feature that you want is unlocked by Haas issuing a "KEY" to enter. I think Funac used this along time ago and they were able to crack it but do not know about the Haas machines.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I understand it right, I should put all my encryption code, including the ”key’s” in the bootloader section, and lock SPM and LPM in the bootloader section by programming the fuses.

Thus I must find a) an encryption logarithm + bootloader program not bigger than 4K (AT90USB1287) , b) make my own bootloader interface to lock/unlock program modules.

Does this sound about right? Will an encryption logarithm (MD5 or SHA-1) fit in less than 4K?

Does anybody have a good link to MD5 or SHA-1 C-code, I’ve been Googling around a bit, but the trees are hiding the wood.

Jepael wrote:
Interesting ideas yes. But what if your customer has one of your boards, and another customer sends his EEPROM data or firmware file to the other? Or buys one board with all the features, and starts cloning the firmware and EEPROM information to make new boards with all the features? How do you prevent this?

- Jani

Moving the lock/unlock function into the bootloader section and disabling SPM and LPM in the bootloader section, should prevent this if I’m not mistaking.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

http://en.wikipedia.org/wiki/MD5
http://en.wikipedia.org/wiki/SHA...

But as said above it doesn't need to be as cryptographically secure as those even. Just some algorithm you do to the data that the user cannot predict. Let's say you just do an 8 bit checksum say:

uint8_t i, sum;
for (i=0, sum=0; i

If you then send this the key string that enables functions 1 and 2:

"mary had a little lamb"

the sum is 0xF1 - I proved that with this short PC program:

#include 
#include 

int main(void) {
	unsigned char i, sum;
	char key_string[] = "mary had a little lamb";

	for (i=0, sum=0; i

So in your AVR code you then have:

if (sum == (uint8_t)0xF1) {
  // set bits in EEEPROM to say that function 1/2 are enabled
}

If the key string had been the following to enable functions 1,2,3,4:

"humpty dumpty sat on a wall"

then the sum would be 0x20. So in the AVR code you also have:

else if (sum == (uint8_t)0x20) {
  // set bits in EEEPROM to say that function 1/2/3/4 are enabled
}

Now this "hash" is not very secure as there are only 256 possible outcomes and if I started with the "mary had a little lamb" key and just changed the 'm' of mary to every character in the 256 character set I'd eventually hit the one that made the sum 0x20 and could use that to also enable functions 3 and 4. IN the code page I use that would be when the string was:

"£ary had a little lamb"

Only thing is that the "hacker" doesn't know it's that simple - but he might stumble across this (in fact just use "a", "b", "c" and when he hit " " he'd be in!) but then again he might not.

If you now enhanced the algoritm to just a 16 bit checksum it would have 65536 combinations and so on.

What MD5 and SHA offer is a routine that has billions of combinations and no way to predict the influence of chaging even a single character in the input string. The MD5 sum of the humpty phrase is:

716c539ba6aa51ab33c1db18d7ffbb14

and the MD5 sum of the mary phrase is:

fa198d47557433b6b99e8ac6d3cca6eb

But something like MD5 or SHA is probably more cryptographically strong than you actually require here (and they are, because of all the floating point maths, going to be BIG routines for an AVR)

Cliff

PS I suggested delivering the key.txt containing "mary had a little lamb" on an SD card above simply because you were looking for a physical "key". But again, as suggested above, you could just as easily have a UART interface with a command that puts it into "accept key string mode" and then play it the piece of text to open the door that way.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Cliff.

Say I use a 16 or 32 bit CRC and implement it the way you explained, then the resulting sum will always be the same for the same ‘key’ entered. Thus if one user send the ‘key’ to a second user, the second user could unlock the futures with the same ‘key’, this is something I want to avoid.

What I mean is, taking your example, "mary had a little lamb" may unlock functions 1 and 2 of one unit only, no other units may be able to be unlocked with the same ‘key’.

What would be the best way for doing that? ‘AND’ the resulting sum (or the ‘key’ before CRC) with a unique serial number, shifting it, adding it or a combination of them all?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah now in that case you are going to need an individual identity in each AVr that you ship out. Let's say that the first one you sell has EEPROM location 0 set to 0x00 then the next one has it set to 0x01 and so on. You still play in the "mary had a little lamb" and it still comes up with a sum of 0xF1 but now, before you do the "if (sum == N)" you actually do a:

sum += contents of EEPROM location 0;

then you do:

if (sum == (uint8_t)0xF1) { 
  // set bits in EEEPROM to say that function 1/2 are enabled 
}

So the first customer, because that location is holding 0x00 gets functions 1 and 2 enabled. But the second customer will be doing an:

if (0xF2 == (uint8_t)0xF1) { 
  // set bits in EEEPROM to say that function 1/2 are enabled 
}

comparison (because 0x01 was added to 0xF1) so "mary had a little lamb" will not unlock his functions.

In fact, in this very simplistic case (because the difference is only 0x01) he could get it to work by reducing the ASCII value of any character in the string by 0x01. So make the 'm' of "mary" and 'l' say?

"lary had a little lamb"

has a (simple) sum 0xF0 and when you add on his "unique identifier" (the 0x01 in EEPROM) this becomes the required 0xF1 sum to perform the unlock.

Again this algorithm is clearly too insecure as customer 0 could talk to customer 1, notice that one of them was told

"mary had a little lamb"

and the other was told

"lary had a little lamb"

so that when the first later upgraded to:

"humpty dumpty sat on a wall"

it wouldn't be beyond the realms of possibility that they'd work out that customer 1 could use:

"gumpty dumpty sat on a wall"

to also get functions 3 and 4.

However you can hopefully see the key principle. For code strings to be unique each product has to have a unique ID number of some sort (but probably not just 0x00, 0x01...)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well yes, that's what I thought and also why I was firstly thinking about using the unique serial number from the data flash memory (AT45DB642D), which I’m using in my project. But I can as easily, if not more easily, place a unique number in the boot loader (but then I need to flash a ‘unique’ boot loader for every unit).

As you mentioned Cliff, adding the CRC output with a unique number would be too simplistic, thus I need something more complex, but more important, that the final result output would be a unique number. Thus I probably will need some XOR operations and some shifting.

So I’ll have to make my own logarithm from the CRC outcome in combination with a unique number. I can understand that people don’t like to talk to deep about that kind of things, after all its meant to protect your business income.

Thanks again Cliff.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Thus I probably will need some XOR operations and some shifting.

That would appear to be a description of "CRC" right there! ;)

Maybe try a google for "hash algorithms" - there's maybe some half way house between a simple checksum/CRC and a full blown MD5. Or like you say, just make something up.

Cliff

EDIT: this page looks like fun:

http://www.partow.net/programmin...

and the download of C source at the bottom:

http://www.partow.net/downloads/...

has a lot of really small, tight looking hash functions that could be used.