Store variable string in avr flash space

Does anybody know how i can store a variable string in the flash of the arduino.

If I store something in the flash of the avr using this method: prog_char string_0[] PROGMEM = "lalalala";

everything goes wright

But if i use this method: String pass = "lalalala"; prog_char string_0[] PROGMEM = pass;

i get errors of which i can solve to be changing the script to this: prog_char string_0[8] PROGMEM = {pass};

but after that I am stuck at this error: cannot convert 'String' to 'prog_char'

I'm stuck at the moment because I find examples everywhere of using the library pgmspace.h but with all the examples the string is hard coded and not stored first in a variable string.

I get a lot of weird errors when i try to store other kinds of variables aswell. They never seem to work flawless.

So does anybody know a tutorial or example of a variable string being stored in the avr flash space.

For security reasons I want to store the string in the avr flash due to security reasons so eeprom is no option as it is not cleared when a new program get burned to the chip.

Flash is ROM; you cannot store a variable in ROM. There is little point storing a String in ROM either, because you can't manipulate it, and manipulating String objects is probably the only advantage they have over ordinary C strings. You can easily store constant C strings in flash however.

But what for can pgmspace then be used?

Could you explain this because in the code you can store a value in flash this way: prog_char string_0[] PROGMEM = "lalalala"; Or are those just pointers for the compiler?

No, that's a [u]constant[/u] string (note the small initial "s"). Can you tell us why you want to use a String?

If you want to store data in non-volatile memory in the Arduino, have a look at the EEPROM and its associated library.

Well the problem i have is that i have to store an encryption key on the arduino. This is not hard coded in there but set later using software on the pc. I first stored the key in the eeprom but the problem with that is that you can just load a read eeprom program on the board because it is going to be open source and will run the arduino bootloader.

So my idea was to flash the arduino with the program including the bootloader and enable the lockbit. But now that i think of it will the arduino IDE still be able to upload programs when the lockbit is enabled? Okay but my idea was to store the key in the flash instead of eeprom so you would not be able to read the key from it because the lockbit is enabled.

But now that i think about it would that even work?

And if not do you or anybody else know a way to store a encryption key safely on the arduino without hackers being able to read it easily by loading a new program? I don't mind them having to go trough the trouble of physically opening the chip and reading the memory it does not have to be that secure.

Create a randomly generated block of memory as part of your sketch in progmem; then set the code by storing the beginning and end of each segment (presumably this code is longer than a few bytes) in EEPROM. Since once they read the EEPROM the sketch will have been deleted, it should be reasonably secure, unless they have a hardware programmer (which can dump both flash and EEPROM to a computer).

Okay but storing those randomly generated bytes in program is possible from the avr. Because the application will be loading the same firmware on a bunch of pcb's and it's going to be open source. So flooding the eeprom with random data apart from a couple of scattered addresses with the actual key. But it would mean having the avr randomly generate the addresses once on first boot and store them in the flash which can not be achieved right?

Pre setting the addresses is no option because of the open firmware.

Since the bytes are randomly generated, each time the bytes are burned it should have a different permutation. You read in this permutation from the computer side, and write the addresses of the desired bytes back to the device. And you can just as easily use EEPROM instead of PROGMEM if necessary.

How do you get those bytes being randomly generated each time I burn it to a chip, may I ask? I just want to use one hex file that i can burn to all the pcb's. If i can randomly generate 72 pointers to addresses in the EEPROM and store those pointers in the flash memory that would solve my problem. 72 new addresses have to be generated for each chip without hard coding them in how could I do that?

If you would go through the process to write random values to EEPROM, read the values back and then hard code an address to the values to make up your key wouldn't it just be easier to randomly generate and hardcode the key itsself in the first place?

That's the direction I think I'd investigate, post process your .hex file, replace the key values with the required random ones and regenerate the checksums. Just include this process before every burn of your production run, you could even build a dedicated burner board that reads your production HEX off an sd card or similar and handles the ISP and key generation as a standalone unit.

If I understand this, you need to have open source code, yet private keys, and want each computer to be different key-wise. As already mentioned, the program code can only be read, not written once you install it on the Arduino, so you'll need to generate a random pool of data on each computer when run. Depending on your security, this is not a trivial thing - we've had discussions on the forum before about random, and real 'random' is very hard without special help. If 'somewhat' random works, here's some code:

This will generate a random number that is unique to the computer, assuming you have an unused analog pin (it needs it for the random bits).

Also, if you plan to reuse this random pool/key, then you'll need to store it from run to run of the program, which means you'll need to place it in eprom.

Timen: How do you get those bytes being randomly generated each time I burn it to a chip, may I ask?

Use a flag in eprom - when you start up, check if the flag is present, and if not, generate and store both a key and the flag. The next time, the flag is there, so you'll use the generated key from then on.

From what I can read of the Atmega328 datasheet, if you set the lock bit it also locks the EEPROM. I think you can reprogram if you first do a "chip erase" but I'm not sure.

However generating a random key might be quite hard. After all, without access to some random data source, it is likely that each one will have a similar "random" sequence in it.

Also, where the hackers coming from? The ones that originally burn the chip? Or if the chip falls into the wrong hands?

If they are the ones that burn the chip in the first place, they just change your burning procedure to not lock the program memory (or modify the program to report via the serial port what the key is).

If you trust the original users (but worry about what happens to the chip later) you could just get them to modify the source and key in some sort of hex sequence, which they randomly generate.

The way I get the key now (i use this way because I need the flash space so can't include md5 and sha1 in the source) The arduino boots up and checks if the key received flag is present if that is not true than it sends a command to a piece of software on a mac or pc that "randomly" generates 8 char code (this is for registration use on the server). Than it generates the MD5 hash of that code and a sha1 hash of the md5 string. The md5 string is the 32 bit encryption key used for aes and the sha1 is the identification key.

It sends the sha1 and md5 to the arduino (I don't want to store them on the pc) and than the normal program starts working and the arduino starts getting the data of the internet.

The md5 and Sha1 is stored in the EEPROM, but the major concern i have about that is that if a hacker gets in to the pc he can actually upload the arduino example sketch EEprom read with no problem because I am supporting the arduino boot loader. And than just read the key of the serial interface.

OKay I think I have a solution.

I want to put an encrypted bootloader on there this would mean not being able to upload sketches directly for arduino so I won't be using it for developing but for the final product I want to upload a secure bootloader so I can do updates but no one else can. Offcourse you could erase the whole chip but that includes the EEPROM if I am right.

Do be aware that you're not going to be able to stop somebody with a hardware AVR programmer from reading and disassembling the hex from both the flash memory and the EEPROM - nothing forces you to use the bootloader, after all.

If the hacker can physically get to the Arduino, there's no real way to protect, since there are devices you can plug in to take control of everything, including eprom. If however, they cannot physically get to the Arduino (say, a locked case), then you'd still have to prevent them using the USB. To do that, I'd recommend using a separate USB serial line for communication (you can get these online for <$5), and not giving them access to the builtin USB. If that's not an option, then you will have to do your own bootloader, and possibly cut some traces on the circuit board, since by default the PC has total control of the Arduino unless you change something.

I just want to rule out the option of it being hacked over usb. So I was thinking of using a boot loader that has the encryption key locked in there and only programs encrypted with the same key will run. So I can distribute updates and if someone just wants to make it do something else be my guest erase the whole chip and put whatever you want on there.

Also I was thinking of putting a sort of public key in the locked boot loader but would i be able to access that from the program that is running not the boot loader?

I don't know if you can add readable data to the bootloader area - but even if your code can, that means another's can as well.

From the sound of it, you might want to use a separate USB for communication, which will let you lock out uploads and updating, while still communicating with the device. For that, you'll need to use a ttl-usb board, and the softwareserial drivers. If this is of interest, I set up one myself (caution: beginner level), that gives you an idea how to do it:

The alternative is to somehow lock out programming across the built in USB, possibly by cutting traces on the PC.