+ memcpy(tag.sectors[blocknr],rx,4);
+ blocknr++;
+ } else {
+
+ if(blocknr == 1){
+ //store password in block1, the TAG answers with Block3, but we need the password in memory
+ memcpy(tag.sectors[blocknr],tx,4);
+ }else{
+ memcpy(tag.sectors[blocknr],rx,4);
+ }
+
+ blocknr++;
+ if (blocknr > 7) {
+ DbpString("Read succesful!");
+ bSuccessful = true;
+ return false;
+ }
+ *txlen = 10;
+ tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2);
+ tx[1] = ((blocknr^7) << 6);
+ }
+ } break;
+
+ // Unexpected response
+ default: {
+ Dbprintf("Uknown frame length: %d",rxlen);
+ return false;
+ } break;
+ }
+ return true;
+}
+
+bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+ // Reset the transmission frame length
+ *txlen = 0;
+
+ if(bCrypto) {
+ hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8);
+ }
+
+ // Try to find out which command was send by selecting on length (in bits)
+ switch (rxlen) {
+ // No answer, try to resurrect
+ case 0: {
+ // Stop if there is no answer while we are in crypto mode (after sending NrAr)
+ if (bCrypto) {
+ // Failed during authentication
+ if (bAuthenticating) {
+ DbpString("Authentication failed!");
+ return false;
+ } else {
+ // Failed reading a block, could be (read/write) locked, skip block and re-authenticate
+ if (blocknr == 1) {
+ // Write the low part of the key in memory
+ memcpy(tag.sectors[1],key+2,4);
+ } else if (blocknr == 2) {
+ // Write the high part of the key in memory
+ tag.sectors[2][0] = 0x00;
+ tag.sectors[2][1] = 0x00;
+ tag.sectors[2][2] = key[0];
+ tag.sectors[2][3] = key[1];
+ } else {
+ // Just put zero's in the memory (of the unreadable block)
+ memset(tag.sectors[blocknr],0x00,4);
+ }
+ blocknr++;
+ bCrypto = false;
+ }