- // Broadcast for a card, WUPA (0x52) will force response from all cards in the field
- ReaderTransmitShort(wupa);
- // Receive the ATQA
- ReaderReceive(receivedAnswer);
- // Transmit SELECT_ALL
- ReaderTransmit(sel_all,sizeof(sel_all));
- // Receive the UID
- ReaderReceive(receivedAnswer);
- // Construct SELECT UID command
- // First copy the 5 bytes (Mifare Classic) after the 93 70
- memcpy(sel_uid+2,receivedAnswer,5);
- // Secondly compute the two CRC bytes at the end
- AppendCrc14443a(sel_uid,7);
-
- byte_t nt_diff = 0;
- LED_A_OFF();
- byte_t par = 0;
- byte_t par_mask = 0xff;
- byte_t par_low = 0;
- int led_on = TRUE;
-
- tracing = FALSE;
- byte_t nt[4];
- byte_t nt_attacked[4];
- byte_t par_list[8];
- byte_t ks_list[8];
- num_to_bytes(parameter,4,nt_attacked);
-
- while(TRUE)
- {
+ while (true) {
+ if(!iso14443a_select_card(uid, NULL, &cuid)) {
+ Dbprintf("Can't select card");
+ break;
+ };
+
+ if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
+ Dbprintf("Auth error");
+ break;
+ };
+
+ if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {
+ Dbprintf("Write block error");
+ break;
+ };
+
+ if(mifare_classic_halt(pcs, cuid)) {
+ Dbprintf("Halt error");
+ break;
+ };
+
+ isOK = 1;
+ break;
+ }
+
+ // ----------------------------- crypto1 destroy
+ crypto1_destroy(pcs);
+
+// DbpString("WRITE BLOCK FINISHED");
+
+ // add trace trailer
+ uid[0] = 0xff;
+ uid[1] = 0xff;
+ uid[2] = 0xff;
+ uid[3] = 0xff;
+ LogTrace(uid, 4, 0, 0, TRUE);
+
+ UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
+
+ LED_B_ON();
+ UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+ LED_B_OFF();
+
+
+ // Thats it...
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LEDsoff();
+// tracing = TRUE;
+
+}
+
+// Return 1 if the nonce is invalid else return 0
+int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
+ return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
+ (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
+ (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// MIFARE nested authentication.
+//
+//-----------------------------------------------------------------------------
+void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
+{
+ // params
+ uint8_t blockNo = arg0;
+ uint8_t keyType = arg1;
+ uint64_t ui64Key = 0;
+
+ ui64Key = bytes_to_num(datain, 6);
+
+ // variables
+ uint8_t targetBlockNo = blockNo + 1;
+ uint8_t targetKeyType = keyType;
+ int rtr, i, j, m, len;
+ int davg, dmin, dmax;
+ uint8_t uid[8];
+ uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;
+ uint8_t par_array[4];
+ nestedVector nvector[3][10];
+ int nvectorcount[3] = {10, 10, 10};
+ int ncount = 0;
+ UsbCommand ack = {CMD_ACK, {0, 0, 0}};
+ struct Crypto1State mpcs = {0, 0};
+ struct Crypto1State *pcs;
+ pcs = &mpcs;
+ uint8_t* receivedAnswer = mifare_get_bigbufptr();
+
+ // clear trace
+ traceLen = 0;
+ tracing = false;
+
+ iso14443a_setup();
+
+ LED_A_ON();
+ LED_B_ON();
+ LED_C_OFF();
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(200);
+
+ davg = dmax = 0;
+ dmin = 2000;
+
+ // test nonce distance
+ for (rtr = 0; rtr < 10; rtr++) {