Can't write encrypted password to RFID card

Hello, I'm trying to save an encrypted String onto a Mifare RFID chip. I have the encryption bit figured out, I even encode it into base64, so that it saves on the card more easily, but have encountered issues when writing to the tag. The RFID library inits fine (but only if init() is called in setup), but then it just never detects the tag.

I have ruled out any hardware issue, as the example sketch works just fine. Running out of memory also can't be the problem, I have pretty much the same amount of free ram as the example.

I'm using an Arduino Nano and the only thing connected to it is a RFID-RC522 module. The code is here:

#include <Crypto.h>
#include <AES.h>
#include <string.h>
#include "base64.hpp"
#include "EasyMFRC522.h"

// Heslo k zašifrování
const char PROGMEM pass[] = "UltraSuperSecret69_!";

EasyMFRC522 rfid(10, 5);

AESTiny128 aes;

const byte PROGMEM aes_key[] = { 0x34, 0x34, 0x32, 0x38, 0x34, 0x37, 0x32, 0x42, 0x34, 0x42, 0x36, 0x32, 0x35, 0x30, 0x36, 0x35 };
const byte PROGMEM aes_iv[] = { 0x77, 0x77, 0x77, 0x2e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x7a, 0x21 };

#define BLOCK 1

uint8_t encPass[] = {0};
unsigned char pass64[255];
unsigned int b64Len;

char stringBuffer[255];

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

  while (!Serial)
    ;

  if (aes.setKey(aes_key, sizeof(aes_key))) {
    Serial.println(F("Setting key succeeded"));
  } else {
    Serial.println(F("An error occured"));
  }

  Serial.flush();
  aes.encryptBlock(encPass, pass);
  Serial.println(F("encryption over"));

  b64Len = encode_base64(encPass, strlen((char*) encPass), pass64);

  String s = pass64;

  Serial.print(F("Encryption complete ("));
  Serial.print(b64Len);
  Serial.print(F("B): "));
  Serial.println(s);

  rfid.init();

  display_freeram();
}

void loop() {
  Serial.println();
  Serial.println(F("READY TO WRITE"));

  bool success = false;
  do {
    // returns true if a Mifare tag is detected
    success = rfid.detectTag();
    delay(50); //0.05s
  } while (!success);

  Serial.println(F("TAG DETECTED!"));

  strcpy(stringBuffer, pass64);

  if (rfid.writeFile(BLOCK, "Pass", (byte*)stringBuffer, strlen(stringBuffer) + 1) >= 0) {
    Serial.print(F("WRITING SUCCESSFUL"));
  } else {
    Serial.print(F("WRITING FAILED"));
    Serial.print(rfid.writeFile(BLOCK, "Pass", (byte*)stringBuffer, strlen(stringBuffer) + 1));
  }

  rfid.unselectMifareTag();

  delay(2000);
}

void display_freeram() {
  Serial.print(F("- SRAM left: "));
  Serial.println(freeRam());
}

int freeRam() {
  extern int __heap_start, *__brkval;
  int v;
  return (int)&v - (__brkval == 0
                    ? (int)&__heap_start : (int) __brkval);
}

Unfortunately you failed to provide a link to the AES.h library you're using. So this is an educated wild guess: You don't provide enough memory for the result of the encryptBlock method.

1 Like

Oh, I'm sorry. Here it is: Arduino Cryptography Library: AESTiny128 Class Reference

I think you are right. I don't think a 1-byte buffer is big enough.

How big is the encrypted password? The password itself is 20 bytes but I think AES128 uses 16-byte blocks so it will likely need two blocks (32 bytes) for the encryption.

I would try:
uint8_t encPass[32] = {0};

1 Like

No, that didn't fix it. The problem is not in the encryption itself, but in writing the string onto the chip card. I can see the encoded password when I print it, it just doesn't get to write the password, because it never detects a tag.

Have you changed the code and tried again? The problem isn't that the password is not encrypted but that the encryption corrupts your memory and any later step might fail randomly.

1 Like

Oh, can that happen? Should I just randomly add/remove code to fix it, or is there another way to fix/prevent it?

This will be a problem. The encrypted password is binary, not a string. You can't use 'strlen()' on binary. I would try:
sizeof encPass

1 Like

I would start from the beginning. You know the example RFID sketch works so start with that. Then add the Crypto stuff one line at a time to see when, exactly, your sketch stops detecting cards. That will go a long way toward figuring out why.

NOTE: I don't think the Crypto library can deal with keys or plaintext in PROGMEM so for now you should not put PROGMEM anywhere in your sketch.

1 Like

Yes, fix the mentioned errors. The memory corruption results from having code that doesn't provide the correct buffer sizes. johnwasser pointed you to the main problem in post #4.

1 Like

Thank you all for your help! I think I managed to get it working, but the RFID module has just failed. The LED doesn't light up and it's not communicating with the arduino at all. I think some of the problems could have also been caused by the thing going out, it was from China, after all. Either that or I somehow fried it. I will get a new one and get back to you someday :slight_smile:

Just fixed the problem. The crypto library I used seems to be broken, so I used this one: GitHub - spaniakos/AES: AES for microcontrollers (Arduino & Raspberry pi). Works like a charm!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.