int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){ int len; // load key, keynumber uint8_t data[2]={0x0a, 0x00}; uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); if (len == 1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; } if (len == 12) { if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], receivedAnswer[10],receivedAnswer[11]); } memcpy(blockData, receivedAnswer, 12); return 0; } return 1; }
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t par[3] = {0}; // enough for 18 parity bits uint8_t d_block[18] = {0x00}; uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); return 1; } memcpy(d_block, blockData, 16); AppendCrc14443a(d_block, 16); ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); len = ReaderReceive(receivedAnswer, receivedAnswerPar); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); return 2; } return 0; }
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { // variables uint16_t len; uint8_t bt[2]; uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // command MIFARE_CLASSIC_READBLOCK len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; } if (len != 18) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: card timeout. len: %x", len); return 2; } memcpy(bt, receivedAnswer + 16, 2); AppendCrc14443a(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd CRC response error."); return 3; } memcpy(blockData, receivedAnswer, 14); return 0; }
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t bt[2]; uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; } if (len != 18) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len); return 2; } memcpy(bt, receivedAnswer + 16, 2); AppendCrc14443a(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error."); return 3; } memcpy(blockData, receivedAnswer, 14); return 0; }
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { // variables int len; uint8_t bt[2]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_READBLOCK len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; } if (len != 18) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: card timeout. len: %x", len); return 2; } memcpy(bt, receivedAnswer + 16, 2); AppendCrc14443a(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd CRC response error."); return 3; } memcpy(blockData, receivedAnswer, 16); return 0; }
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { // variables uint16_t len; uint8_t par[3] = {0}; // enough for 18 parity bits uint8_t d_block[18]; uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); return 1; } memset(d_block,'\0',18); memcpy(d_block, blockData, 16); AppendCrc14443a(d_block, 16); ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); // Receive the response len = ReaderReceive(receivedAnswer, receivedAnswerPar); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); return 2; } return 0; }
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ int len; uint8_t data[17] = {0x00}; data[0] = 0xAF; memcpy(data+1,key,16); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]); return 1; } if (len == 12){ if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], receivedAnswer[10],receivedAnswer[11]); } memcpy(blockData, receivedAnswer, 12); return 0; } return 1; }
void Fpga_print_status(void) { Dbprintf("Fgpa"); if(downloaded_bitstream == FPGA_BITSTREAM_HF) Dbprintf(" mode.............HF"); else if(downloaded_bitstream == FPGA_BITSTREAM_LF) Dbprintf(" mode.............LF"); else Dbprintf(" mode.............%d", downloaded_bitstream); }
// 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO) // cmd = cmd bytes to send // cmd_len = length of cmd // dataout = pointer to response data array int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){ size_t len = 0; size_t wrappedLen = 0; uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00}; uint8_t resp[MAX_FRAME_SIZE]; uint8_t par[MAX_PARITY_SIZE]; wrappedLen = CreateAPDU( cmd, cmd_len, wCmd); if (MF_DBGLEVEL >= 4) { print_result("WCMD <--: ", wCmd, wrappedLen); } ReaderTransmit( wCmd, wrappedLen, NULL); len = ReaderReceive(resp, par); if ( !len ) { if (MF_DBGLEVEL >= 4) Dbprintf("fukked"); return FALSE; //DATA LINK ERROR } // if we received an I- or R(ACK)-Block with a block number equal to the // current block number, toggle the current block number else if (len >= 4 // PCB+CID+CRC = 4 bytes && ((resp[0] & 0xC0) == 0 // I-Block || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 && (resp[0] & 0x01) == pcb_blocknum) // equal block numbers { pcb_blocknum ^= 1; //toggle next block } memcpy(dataout, resp, len); return len; }
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[8];//, ecmd[4]; //uint32_t par=0; dcmd[0] = cmd; dcmd[1] = data[0]; dcmd[2] = data[1]; dcmd[3] = data[2]; dcmd[4] = data[3]; dcmd[5] = data[4]; AppendCrc14443a(dcmd, 6); //Dbprintf("Data command: %02x", dcmd[0]); //Dbprintf("Data R: %02x %02x %02x %02x %02x %02x %02x", dcmd[1],dcmd[2],dcmd[3],dcmd[4],dcmd[5],dcmd[6],dcmd[7]); //memcpy(ecmd, dcmd, sizeof(dcmd)); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, answer_parity); if(!len) { if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); return 2; } return len; }
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { // variables int len, i; uint32_t pos; uint8_t par[3] = {0}; // enough for 18 Bytes to send byte_t res; uint8_t d_block[18], d_block_enc[18]; uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); return 1; } memcpy(d_block, blockData, 16); AppendCrc14443a(d_block, 16); // crypto for (pos = 0; pos < 18; pos++) { d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; par[pos>>3] |= (((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) << (7 - (pos&0x0007))); } ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); // Receive the response len = ReaderReceive(receivedAnswer, receivedAnswerPar); res = 0; for (i = 0; i < 4; i++) res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], i)) << i; if ((len != 1) || (res != 0x0A)) { if (MF_DBGLEVEL >= 1) Dbprintf("Cmd send data2 Error: %02x", res); return 2; } return 0; }
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){ /* ARG0 contains flags. 0x01 = init card. 0x02 = Disconnect 0x03 */ uint8_t flags = arg0; size_t datalen = arg1; uint8_t resp[RECEIVE_SIZE]; memset(resp,0,sizeof(resp)); if (MF_DBGLEVEL >= 4) { Dbprintf(" flags : %02X", flags); Dbprintf(" len : %02X", datalen); print_result(" RX : ", datain, datalen); } if ( flags & CLEARTRACE ) clear_trace(); if ( flags & INIT ){ if ( !InitDesfireCard() ) return; } int len = DesfireAPDU(datain, datalen, resp); if (MF_DBGLEVEL >= 4) print_result("ERR <--: ", resp, len); if ( !len ) { OnError(2); return; } // reset the pcb_blocknum, pcb_blocknum = 0; if ( flags & DISCONNECT ) OnSuccess(); cmd_send(CMD_ACK,1,len,0,resp,len); }
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[19]; int len; dcmd[0] = cmd; memcpy(dcmd+1,data,16); AppendCrc14443a(dcmd, 17); ReaderTransmit(dcmd, sizeof(dcmd), timing); len = ReaderReceive(answer, answer_parity); if(!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); len = ReaderReceive(answer,answer_parity); } if(len==1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); return 1; } return len; }
int mifare_classic_halt_ex(struct Crypto1State *pcs) { uint16_t len; uint8_t receivedAnswer[4]; uint8_t receivedAnswerPar[4]; len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("halt error. response len: %x", len); return 1; } return 0; }
// mifare ultralight commands int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){ uint16_t len; uint8_t resp[4]; uint8_t respPar[1]; uint8_t key[4] = {0x00}; memcpy(key, keybytes, 4); Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL); if (len != 4) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len); return 0; } if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0],resp[1],resp[2],resp[3]); memcpy(pack, resp, 4); return 1; }
void printConfig() { Dbprintf("LF Sampling config"); Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1)); Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold); }
//----------------------------------------------------------------------------- // Set up a communication channel (Card Select, PPS) // Returns 0 on success or a non-zero error code on failure //----------------------------------------------------------------------------- int EPA_Setup() { int return_code = 0; uint8_t uid[10]; uint8_t pps_response[3]; uint8_t pps_response_par[1]; iso14a_card_select_t card_select_info; // first, look for type A cards // power up the field iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); // select the card return_code = iso14443a_select_card(uid, &card_select_info, NULL); if (return_code == 1) { // send the PPS request ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL); return_code = ReaderReceive(pps_response, pps_response_par); if (return_code != 3 || pps_response[0] != 0xD0) { return return_code == 0 ? 2 : return_code; } Dbprintf("ISO 14443 Type A"); iso_type = 'a'; return 0; } // if we're here, there is no type A card, so we look for type B // power up the field iso14443b_setup(); // select the card return_code = iso14443b_select_card(); if (return_code == 1) { Dbprintf("ISO 14443 Type B"); iso_type = 'b'; return 0; } Dbprintf("No card found."); return 1; }
int mifare_ultra_halt() { uint16_t len; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("halt error. response len: %x", len); return 1; } return 0; }
void printConfig() { Dbprintf("LF Sampling config: "); Dbprintf(" [q] divisor: %d ", config.divisor); Dbprintf(" [b] bps: %d ", config.bits_per_sample); Dbprintf(" [d] decimation: %d ", config.decimation); Dbprintf(" [a] averaging: %d ", config.averaging); Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold); }
// send X byte basic commands int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[data_size+3]; dcmd[0] = cmd; memcpy(dcmd+1,data,data_size); AppendCrc14443a(dcmd, data_size+1); ReaderTransmit(dcmd, sizeof(dcmd), timing); int len = ReaderReceive(answer, answer_parity); if(!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd); len = ReaderReceive(answer,answer_parity); //return 0; } return len; }
int mifare_ultra_halt(uint32_t uid) { uint16_t len; // Mifare HALT uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len); return 1; } return 0; }
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[20] = {0x00}; dcmd[0] = cmd; memcpy(dcmd+1,data,17); AppendCrc14443a(dcmd, 18); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, answer_parity); if(!len){ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); return 1; } return len; }
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { // variables uint16_t len; // Mifare HALT uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len); return 1; } return 0; }
bool InitDesfireCard(){ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); set_tracing(TRUE); byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00}; iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf; int len = iso14443a_select_card(NULL,card,NULL,true,0); if (!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); OnError(1); return false; } return true; }
//---------------------------------------------------------------------------- // Uncompress (inflate) the FPGA data. Returns one decompressed byte with // each call. //---------------------------------------------------------------------------- static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data compressed_fpga_stream->next_out = output_buffer; compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; fpga_image_ptr = output_buffer; int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); if (res != Z_OK) { Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); } if (res < 0) { return res; } } uncompressed_bytes_cnt++; return *fpga_image_ptr++; }
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t d_block[5] = {0x00}; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK d_block[0]= blockNo; memcpy(d_block+1,blockData,4); //AppendCrc14443a(d_block, 6); len = mifare_sendcmd(0xA2, d_block, sizeof(d_block), receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); return 1; } return 0; }
//----------------------------------------------------------------------------- // Read the file EF.CardAccess and save it into a buffer (at most max_length bytes) // Returns -1 on failure or the length of the data on success // TODO: for the moment this sends only 1 APDU regardless of the requested length //----------------------------------------------------------------------------- int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length) { // the response APDU of the card // since the card doesn't always care for the expected length we send it, // we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame) uint8_t response_apdu[262]; int rapdu_length = 0; // select the file EF.CardAccess rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess, sizeof(apdu_select_binary_cardaccess), response_apdu); if (rapdu_length < 6 || response_apdu[rapdu_length - 4] != 0x90 || response_apdu[rapdu_length - 3] != 0x00) { DbpString("Failed to select EF.CardAccess!"); return -1; } // read the file rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary, sizeof(apdu_read_binary), response_apdu); if (rapdu_length <= 6 || response_apdu[rapdu_length - 4] != 0x90 || response_apdu[rapdu_length - 3] != 0x00) { Dbprintf("Failed to read EF.CardAccess!"); return -1; } // copy the content into the buffer // length of data available: apdu_length - 4 (ISO frame) - 2 (SW) size_t to_copy = rapdu_length - 6; to_copy = to_copy < max_length ? to_copy : max_length; memcpy(buffer, response_apdu+2, to_copy); return to_copy; }
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t d_block[8]; uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // command MIFARE_CLASSIC_WRITEBLOCK memset(d_block,'\0',8); d_block[0]= blockNo; memcpy(d_block+1,blockData,4); AppendCrc14443a(d_block, 6); //i know the data send here is correct len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); return 1; } return 0; }
// Download the fpga image starting at current stream position with length FpgaImageLen bytes static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen); int i=0; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON; HIGH(GPIO_FPGA_ON); // ensure everything is powered on SpinDelay(50); LED_D_ON(); // These pins are inputs AT91C_BASE_PIOA->PIO_ODR = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // PIO controls the following pins AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // Enable pull-ups AT91C_BASE_PIOA->PIO_PPUER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // setup initial logic state HIGH(GPIO_FPGA_NPROGRAM); LOW(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_DIN); // These pins are outputs AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_NPROGRAM | GPIO_FPGA_CCLK | GPIO_FPGA_DIN; // enter FPGA configuration mode LOW(GPIO_FPGA_NPROGRAM); SpinDelay(50); HIGH(GPIO_FPGA_NPROGRAM); i=100000; // wait for FPGA ready to accept data signal while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) { i--; } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } for(i = 0; i < FpgaImageLen; i++) { int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); if (b < 0) { Dbprintf("Error %d during FpgaDownload", b); break; } DownloadFPGA_byte(b); } // continue to clock FPGA until ready signal goes high i=100000; while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } LED_D_OFF(); }
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { // variables int len; uint32_t pos; uint8_t tmp4[4]; uint8_t par[1] = {0}; byte_t nr[4]; uint32_t nt, ntpp; // Supplied tag nonce uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // Transmit MIFARE_CLASSIC_AUTH len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len); if (len != 4) return 1; // "random" reader nonce: nr[0] = 0x55; nr[1] = 0x41; nr[2] = 0x49; nr[3] = 0x92; // Save the tag nonce (nt) nt = bytes_to_num(receivedAnswer, 4); // ----------------------------- crypto1 create if (isNested) crypto1_destroy(pcs); // Init cipher with key crypto1_create(pcs, ui64Key); if (isNested == AUTH_NESTED) { // decrypt nt with help of new key nt = crypto1_word(pcs, nt ^ uid, 1) ^ nt; } else { // Load (plain) uid^nt into the cipher crypto1_word(pcs, nt ^ uid, 0); } // some statistic if (!ntptr && (MF_DBGLEVEL >= 3)) Dbprintf("auth uid: %08x nt: %08x", uid, nt); // save Nt if (ntptr) *ntptr = nt; // Generate (encrypted) nr+parity by loading it into the cipher (Nr) par[0] = 0; for (pos = 0; pos < 4; pos++) { mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos]; par[0] |= (((filter(pcs->odd) ^ oddparity(nr[pos])) & 0x01) << (7-pos)); } // Skip 32 bits in pseudo random generator nt = prng_successor(nt,32); // ar+parity for (pos = 4; pos < 8; pos++) { nt = prng_successor(nt,8); mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff); par[0] |= (((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) << (7-pos)); } // Transmit reader nonce and reader answer ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); // Receive 4 byte tag answer len = ReaderReceive(receivedAnswer, receivedAnswerPar); if (!len) { if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); return 2; } memcpy(tmp4, receivedAnswer, 4); ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0,0); if (ntpp != bytes_to_num(tmp4, 4)) { if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Error card response."); return 3; } return 0; }