2

I'm currently using an Arduino Uno R3 and an RFID-RC522 with https://github.com/miguelbalboa/rfid .

I wrote the following bytes to the trailer block in order to experiment with it:

byte writeBlockContent[blockSize] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0x7, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA };

I wanted to change the default MFRC522::MIFARE_Key key.keyByte so I can read and write to the card using a custom key and leave everything unchanged but I cannot access the sector anymore.

What do I have to do to be able to access the sector again? Code:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
/*
 * Pin connections for UNO:
 * 9  - RST
 * 10 - SDA
 * 11 - MOSI
 * 12 - MISO
 * 13 - SCK
 */
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key; // will hold card info

// Every 4th block is a trailer block that contains access and security info, modulo 4.
const int blockSize = 16;

int writeBlockNumber = 2; // The block we want to write the data.
int readBlockNumber = 2;
byte writeBlockContent[blockSize] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0x7, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA }; // 16 character max
byte readBlockContent[18] = { 0 };

// Will write the data to the block.
int writeBlock(int block, byte data[]) {
  int status;

  if ( (block + 1) % 4 == 0) {
    Serial.println("Warning: Writing on a trailer block!");
    return 0;
  }

  int trailerBlock = block + (4 - block % 4) - 1;
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &mfrc522.uid);
  if ( status != MFRC522::STATUS_OK ) {
    Serial.print("PCD_Authenticate() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return status;
  }

  status = mfrc522.MIFARE_Write(block, data, blockSize);
  if ( status != MFRC522::STATUS_OK ) {
    Serial.print("MIFARE_Write() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return status;
  }
  return MFRC522::STATUS_OK;
}

// Will try to dump the whole card info.
void dumpCard() {
  for(int i = 0; i < blockSize; ++i) {
      Serial.print("Block ");
      Serial.print(i);
      Serial.print(" ");
      if ( readBlock(i, readBlockContent) == MFRC522::STATUS_OK ) {
        printReadBlock();
      }
  }
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

// Will read the block.
// These functions must be called if you wish to read a new card.
//    mfrc522.PICC_HaltA();
//    mfrc522.PCD_StopCrypto1();
int readBlock(int block, byte data[]) {
  int status;
  byte readSize = blockSize + 2;

  int trailerBlock = block + (4 - block % 4) - 1;
  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &mfrc522.uid);

  if ( status != MFRC522::STATUS_OK ) {
    Serial.print("PCD_Authenticate() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return status;
  }

  status = mfrc522.MIFARE_Read(block, data, &readSize);
  if ( status != MFRC522::STATUS_OK ) {
    Serial.print("MIFARE_Read() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return status;
  }

  return MFRC522::STATUS_OK;
}

// Will print the contents of the readBlockContent.
void printReadBlock() {
  for (int i = 0; i < blockSize; ++i) {
    Serial.print(readBlockContent[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" -> ");
  for (int i = 0; i < blockSize; ++i) {
    Serial.write(readBlockContent[i]);
  }

  Serial.println();
}

// Will print the card id that is stored in mfrc522.uid.uidByte
void printCardUid() {
  Serial.print("Card ID: ");
  for (int i = 0; i < mfrc522.uid.size; ++i) {
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

void setup() {
  Serial.begin(9600);
  while (!Serial); // Wait for serial.
  SPI.begin();

  mfrc522.PCD_Init();
  Serial.println("Initialized...");

  // default access key STANDARD KEY 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
  for (int i = 0; i < 6; ++i) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent() ) {
      return;  // No card present, continue.
  } 
  if ( ! mfrc522.PICC_ReadCardSerial() ) {
      // On success this function will return 1 and set the uid struct mfrc522.uid
      return;
  }

  printCardUid();

  // Write data to block.
//  writeBlock(15, writeBlockContent);
//  if ( readBlock(13, readBlockContent) == MFRC522::STATUS_OK )
//    printReadBlock();

  dumpCard();

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}
1

And I quote:

With each memory access the internal logic verifies the format of the access conditions. If it detects a format violation the whole sector is irreversibly blocked.

The only thing that can get you locked out of a sector is incorrectly formatted access bits. As long as you didn't touch those, the sector should still be accessible.

It looks like you tried to change key A and key B. With the transport config, the contents of the sector trailer can only be altered if you authenticate the sector with Key A. Is that what you did? Lets continue then. Since you left the access bits unchanged (right?), it means only key A has R/W access to all blocks (except the manufacturer's) and key B, since it's still readable, can be used to authenticate but can't be used to access blocks. So, if your key change was successful, then you should be able to access the sector with your new key A i.e. {0,0,0,0,0,0}. If it wasn't successful (maybe because authentication failed), then the default key A should still be valid.

  • I tried accessing with A but I still get timeout in communication. Here's what was before in the trailer block: – Metonymy Oct 23 '16 at 11:29
  • Block 11 0 0 0 0 0 0 FF 7 80 69 FF FF FF FF FF FF – Metonymy Oct 23 '16 at 11:30
  • I've tried login with both key A being {0,0,0,0,0,0} and {FF,FF,FF,FF,FA} but it doesn't work. I can read the other blocks using key A {FF, FF, FF, FF, FF, FF } – Metonymy Oct 23 '16 at 11:32
  • @Metonymy Have you tried using the default key A? Wheres the code you used to change the keys? Edit your post. – TisteAndii Oct 23 '16 at 12:18
  • I've tried used the default key, I can only read the other sectors with it. – Metonymy Oct 23 '16 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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