title: Authentication after a read failure of a MIFARE card
body: <p>An arduino and a mfrc522 rfid reader are easy to use to read and write mifare card.</p>
  
  <p>My aim is to use the both key of the card in a sector, some blocks are readable with key A, and some are only readable by key B. </p>
  
  <p>Setting properly the access bits allow this behaviour. So as to try it on the second sector (blocks 4 5 6 7), I set the access bits g0 [0 0 0], g1 [1 0 1], g2 [0 0 0], g3 [1 0 1]  by writting the block 7 with {,0xF5,0xA5,0xA0,0x38,} cf. §8.7 of <a href="https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf" rel="nofollow noreferrer">https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf</a>. Now the block 5 is not readable with keyA but with keyB (g1), and keyB is no more readable (g3). So when I authenticate with keyA an attempt to read the block 5 lead to an error. At this time the others authentications fail, and it is not possible to read the others blocks, though the access bits allow it.</p>
  
  <p>I tried to read the second sector with key B for block 5 and keyA for the others code, it is working. But if I try to read with key A then with keyB in case of failure it is not working.</p>
  
  <p>Extract of the code : </p>
  
  <pre><code>// The sector of interest is the second one : blocks 4 5 6 7
  Serial.println("\nAuthenticate block 0x05 with key B");
  for (i = 4; i &lt; 8; i++) {
        // Block 5 is readable with key B
        status = readblock(i==5?MF1_AUTHENT1B:MF1_AUTHENT1A, i, i==5?keyB:keyA, serial);
        if ( status == MI_ERR) {
             Serial.print(" - Unable to read block nb. 0x");
             Serial.println(i, HEX);
        }
  }
  
  Serial.println("\nAuthenticate with key A then key B if failed");
  for (i = 4; i &lt; 8; i++) {
         // Try to authenticate each block first with the A key.
         status = readblock(MF1_AUTHENT1A, i, keyA, serial);
         if ( status == MI_ERR) {
              Serial.print(" - Try keyB - ");
              status = readblock(MF1_AUTHENT1B, i, keyB, serial);
              if ( status == MI_ERR) {
                   Serial.print(" - Unable to read block nb. 0x");
                   Serial.println(i, HEX);
              }
          }
  }
  </code></pre>
  
  <p>readblock function (authentication and read)</p>
  
  <pre><code>byte readblock(byte mode, byte block, byte *key, byte *serial)
  {
  int j;
   byte data[MAX_LEN];
  byte status = MI_ERR;
  
  // Try to authenticate the block first
  status = nfc.authenticate(mode, block, key, serial);
  if ( status == MI_OK) {
      Serial.print("Authenticated block nb. 0x");
      Serial.print(block, HEX);
      // Reading block i from the tag into data.
      status = nfc.readFromTag(block, data);
      if (status == MI_OK) {
          // If there was no error when reading; print all the hex
          // values in the data.
          Serial.print(" : ");
          for (j = 0; j &lt; 15; j++) {
              Serial.print(data[j], HEX);
              Serial.print(", ");
          }
          Serial.println(data[15], HEX);
      } else
          Serial.print(" - Read failed");
    } else {
      Serial.print("Failed authentication block nb. 0x");
  Serial.print(block, HEX);
  }
    return status;
  }
  </code></pre>
  
  <p>The result is </p>
  
  <pre><code>Authenticate block 0x05 with key B
  Authenticated block nb. 0x4 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Authenticated block nb. 0x5 : AB, CD, EF, 1, 23, 45, 67, 89, 98, 76, 54, 1A, 10, FE, DC, BA
  Authenticated block nb. 0x6 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Authenticated block nb. 0x7 : 0, 0, 0, 0, 0, 0, F5, A5, A0, 38, 0, 0, 0, 0, 0, 0
  
  Authenticate with key A then key B if failed
  Authenticated block nb. 0x4 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Authenticated block nb. 0x5 - Read failed - Try keyB - Failed authentication block nb. 0x5 - Unable to read block nb. 0x5
  Failed authentication block nb. 0x6 - Try keyB - Failed authentication block nb. 0x6 - Unable to read block nb. 0x6
  Failed authentication block nb. 0x7 - Try keyB - Failed authentication block nb. 0x7 - Unable to read block nb. 0x7
  </code></pre>
  
  <p>So I would like to know if it is possible to attempt to read a block with the bad key and then go on reading the block with the othe rkey, and so on.</p>