0

I'm attempting to save a string to EEPROM of an ESP8266 radio and then read it back before I encrypt the data (evenutally I would like to save the encrypted data but I'm simplifing things at the moment). Here is the source code:

#include <Arduino.h>
extern "C" 
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
  byte len = strToWrite.length();
  EEPROM.write(addrOffset, len);
  for (int i = 0; i < len; i++)
  {
    EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
  }
}

String readStringFromEEPROM(int addrOffset)
{
  int newStrLen = EEPROM.read(addrOffset);
  char data[newStrLen + 1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addrOffset + 1 + i);
  }
  data[newStrLen] = '\0'; 
  return String(data);
}


void setup()
{
    Serial.begin(74880);

    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    writeStringToEEPROM(0, "test");
    String retrievedString = readStringFromEEPROM(0);
    uint8_t plaintext = atoi(retrievedString.substring(1,3).c_str());
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
}

and here is the error message:

enter image description here

EDIT**: Found out that the "Save to EEPROM" portion of my code wasn't working so I corrected that. Here is the new code:

#include <Arduino.h>
extern "C" 
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void setup()
{
    Serial.begin(74880);
    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    uint addr = 0;
    struct 
    { 
      uint val = 0;
      char str[16] = "";
    } data;

    EEPROM.begin(512);// commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
    strcpy(data.str,"test");
    EEPROM.put(addr,data);
    EEPROM.commit();  
    EEPROM.get(addr,data);
    Serial.println(String(data.str));

    uint8_t plaintext = atoi(data.str);
    //uint8_t plaintext[16] = "test";
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];
    uint8_t decryptdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, &plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
        status = aes_cbc_decrypt(&cfg, cypherdata, sizeof(cypherdata), iv, decryptdata, KEY_SLOT);
        if (status == ATCA_SUCCESS)
        {
            Serial.print("Decrypted text is : ");
            for (size_t i = 0; i < sizeof(decryptdata); i++)
            {
                Serial.print((char)decryptdata[i]);
            }
            Serial.println("");
        }
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
    delay(1000);
}

Now I'm seeing this in the terminal (no errors on compile!):

encrypted
ERROR Decrypt : ATCA_BAD_PARAMI2C send 1 bytes to addr 0x30: 01

When I change (the aes_cbc_encrypt function expects a length of 16)

sizeof(plaintext)

to

16

I see:

Decrypted text is : ␀␀␀␀␀␀␀␀l��?���?

When I proved that the encrypt/decrypt portion of my code was working, this is what "plaintext" was:

 uint8_t plaintext[16] = "test";
4
  • 2
    No text as image please. You can copy the error message as text into your question and format it the same way as the code
    – chrisl
    Commented Feb 16 at 17:29
  • The function expects a pointer to the data. Try passing it by reference as &plaintext. Though I'm not sure if you really want that. The variable name plaintext suggests, that it should be text. Though it is just a number (8 bit unsigned integer)
    – chrisl
    Commented Feb 16 at 17:36
  • Again, you seem to think, that plaintext contains a text message. It does not. sizeof(plaintext) is always 1, since plaintext has only 1 byte. You are encrypting a single "character", though not really a character, but the binary representation of the number. It really doesn't make any sense to me, that you would encrypt a single byte. Why are you doing the atoi() when assigning plaintext? The commented line suggests, that this should be an array containing a c string.
    – chrisl
    Commented Feb 16 at 20:04
  • chrisl, In the other working code, I had uint8_t plaintext[16] = "test"; Without the EEPROM bit, this worked. When I try replace "test" with data.str, it gives a compile error. If I need to call something other than plaintext, fine. I'm a hardware guy that is trying my best to get better at firmware, so sorry if I'm ignorant about simple things.
    – PhippsTech
    Commented Feb 16 at 20:16

1 Answer 1

0

The function atoi() tries to interpret a string as a textual representation of a number written in decimal. For example, atoi("42") returns the integer 42. Here:

uint8_t plaintext = atoi(data.str);

You are asking it to interpret "test", which does not look like a number. In such a case, atoi() returns zero. I do not know what was your intent, but it was probably not this.

Further down, you have

uint8_t cypherdata[sizeof(plaintext)];
uint8_t decryptdata[sizeof(plaintext)];

Given that plaintext is a single byte, its length is one. Thus this is declaring two arrays of length one. Again, you probably meant something else.


From you comment, I understand that you want plaintext to represent the string "test" as an array of uint8_t. Since both char and uint8_t represent bytes, no conversion is needed. You can simply use the address of the original char array and “pretend” it is the address of an array of uint8_t:

uint8 *plaintext = (uint8_t *) data.str;
2
  • I just what the string "test" stored in EEPROM and then converted in to uint so it can be placed in the aes_cbc_encrypt function. I changed the atoi command to toInt and still get the same thing. I'll edit the post to explain that in the original aes_ebc_encrypt example, I was using uint8 plaintext[16] = "test"; and that was working
    – PhippsTech
    Commented Feb 16 at 21:52
  • that makes sense. That worked and I just put it 16 for the sizeof(plaintext). That should work for now. Thanks!
    – PhippsTech
    Commented Feb 17 at 4:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.