Пример #1
0
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKeys) 
{
	int i, m, len;
	uint8_t isEOF;
	uint32_t uid;
	fnVector * vector = NULL;
	countKeys	*ck;
	int lenVector = 0;
	UsbCommand * resp = NULL;
	
	memset(resultKeys, 0x00, 16 * 6);

	// flush queue
	while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
	
  UsbCommand c = {CMD_MIFARE_NESTED, {blockNo, keyType, trgBlockNo + trgKeyType * 0x100}};
	memcpy(c.d.asBytes, key, 6);
  SendCommand(&c);

	PrintAndLog("\n");

	// wait cycle
	while (true) {
		printf(".");
		if (ukbhit()) {
			getchar();
			printf("\naborted via keyboard!\n");
			break;
		}

		resp = WaitForResponseTimeout(CMD_ACK, 1500);

		if (resp != NULL) {
			isEOF  = resp->arg[0] & 0xff;

			if (isEOF) break;
			
			len = resp->arg[1] & 0xff;
			if (len == 0) continue;
			
			memcpy(&uid, resp->d.asBytes, 4); 
			PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff);
			vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200);
			if (vector == NULL) {
				PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector)); 
				break;
			}
			
			for (i = 0; i < len; i++) {
				vector[lenVector + i].blockNo = resp->arg[2] & 0xff;
				vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff;
				vector[lenVector + i].uid = uid;

				memcpy(&vector[lenVector + i].nt,  (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4);
				memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4);
			}

			lenVector += len;
		}
	}
Пример #2
0
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) 
{
	uint16_t i, len;
	uint32_t uid;
	UsbCommand resp;

	
	StateList_t statelists[2];
	struct Crypto1State *p1, *p2, *p3, *p4;
	
	// flush queue
	WaitForResponseTimeout(CMD_ACK,NULL,100);
	
	UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}};
	memcpy(c.d.asBytes, key, 6);
	SendCommand(&c);

	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
		len = resp.arg[1];
		if (len == 2) {	
			memcpy(&uid, resp.d.asBytes, 4);
			PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8);
			
			for (i = 0; i < 2; i++) {
				statelists[i].blockNo = resp.arg[2] & 0xff;
				statelists[i].keyType = (resp.arg[2] >> 8) & 0xff;
				statelists[i].uid = uid;

				memcpy(&statelists[i].nt,  (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4);
				memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4);
			}
		}
Пример #3
0
int CmdHFDES(const char *Cmd)
{
    //flush
    WaitForResponseTimeout(CMD_ACK,NULL,100);
    CmdsParse(CommandTable, Cmd);
    return 0;
}
Пример #4
0
int CmdHF15CmdInquiry(const char *Cmd) 
{
	UsbCommand resp;
	uint8_t *recv;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	uint8_t *req=c.d.asBytes;
	int reqlen=0;
	
	req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | 
	        ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
	req[1]=ISO15_CMD_INVENTORY;
	req[2]=0; // mask length
	reqlen=AddCrc(req,3);
	c.arg[0]=reqlen;

	SendCommand(&c);
	
	if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
		if (resp.arg[0]>=12) {
		   recv = resp.d.asBytes;
		   PrintAndLog("UID=%s",sprintUID(NULL,&recv[2]));
		   PrintAndLog("Tag Info: %s",getTagInfo(&recv[2]));	
		} else {
			PrintAndLog("Response to short, just %i bytes. No tag?\n",resp.arg[0]);
		}
	} else {
		PrintAndLog("timeout.");
	}
	return 0;
}
Пример #5
0
// fast method to just read the UID of a tag (collission detection not supported)
//		*buf	should be large enough to fit the 64bit uid
// returns 1 if suceeded
int getUID(uint8_t *buf) 
{
	UsbCommand resp;
	uint8_t *recv;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	uint8_t *req=c.d.asBytes;
	int reqlen=0;
	
	for (int retry=0;retry<3; retry++) { // don't give up the at the first try		
		
		req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | 
		        ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
		req[1]=ISO15_CMD_INVENTORY;
		req[2]=0; // mask length
		reqlen=AddCrc(req,3);
		c.arg[0]=reqlen;
	
		SendCommand(&c);
		
		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
			recv = resp.d.asBytes;
			if (resp.arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
			   memcpy(buf,&recv[2],8);
			   return 1;
			} 
		} 
	} // retry
	return 0;
}
Пример #6
0
// fast method to just read the UID of a tag (collission detection not supported)
//		*buf	should be large enough to fit the 64bit uid
// returns 1 if suceeded
int getUID(uint8_t *buf) {

	UsbCommand resp;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?

	c.d.asBytes[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
	c.d.asBytes[1] = ISO15_CMD_INVENTORY;
	c.d.asBytes[2] = 0; // mask length

	AddCrc(c.d.asBytes, 3);
	c.arg[0] = 5; // len

	uint8_t retry;
	
	// don't give up the at the first try			
	for (retry = 0; retry < 3; retry++) {

		clearCommandBuffer();
		SendCommand(&c);
		
		if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
			
			uint8_t resplen = resp.arg[0];
			if (resplen >= 12 && CheckCrc(resp.d.asBytes, 12)) {
			   memcpy(buf, resp.d.asBytes + 2, 8);
			   return 1;
			} 
		} 
	} // retry
	
	if ( retry >= 3 )
		PrintAndLogEx(WARNING, "timeout while waiting for reply.");
	
	return 0;
}
Пример #7
0
int CmdHFDESReader(const char *Cmd)
{
    UsbCommand c  ={CMD_MIFARE_DES_READER, {3, 0x60, 0}};
    SendCommand(&c);

    UsbCommand resp;
	WaitForResponseTimeout(CMD_ACK,&resp,2000);
    return 0;
}  
Пример #8
0
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
	UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};
 	SendCommand(&c);

	UsbCommand resp;
	if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;
	memcpy(data, resp.d.asBytes, blocksCount * 16);
	return 0;
}
Пример #9
0
int CmdHFDESReader(const char *Cmd)
{
    UsbCommand c = { CMD_MIFARE_DES_READER, {3, 0x60, 0} };
    SendCommand(&c);
    UsbCommand resp;
	if (!WaitForResponseTimeout(CMD_ACK,&resp,2000) ){
		PrintAndLog("Command time-out");
		return 1;
	}
    return 0;
}  
Пример #10
0
int CmdPyramidClone(const char *Cmd) {

	char cmdp = param_getchar(Cmd, 0);
	if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_clone();

	uint32_t facilitycode=0, cardnumber=0, fc = 0, cn = 0;
	uint32_t blocks[5];
	uint8_t i;
	uint8_t bs[128];
	memset(bs, 0x00, sizeof(bs));

	if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) return usage_lf_pyramid_clone();

	facilitycode = (fc & 0x000000FF);
	cardnumber = (cn & 0x0000FFFF);
	
	if ( !GetPyramidBits(facilitycode, cardnumber, bs)) {
		PrintAndLog("Error with tag bitstream generation.");
		return 1;
	}

	//Pyramid - compat mode, FSK2a, data rate 50, 4 data blocks
	blocks[0] = T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 4<<T55x7_MAXBLOCK_SHIFT;

	if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q')
		blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 50<<T5555_BITRATE_SHIFT | 4<<T5555_MAXBLOCK_SHIFT;

	blocks[1] = bytebits_to_byte(bs,32);
	blocks[2] = bytebits_to_byte(bs+32,32);
	blocks[3] = bytebits_to_byte(bs+64,32);
	blocks[4] = bytebits_to_byte(bs+96,32);

	PrintAndLog("Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
	PrintAndLog("Blk | Data ");
	PrintAndLog("----+------------");
	for ( i = 0; i<5; ++i )
		PrintAndLog(" %02d | %08" PRIx32, i, blocks[i]);

	UsbCommand resp;
	UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}};

	for ( i = 0; i<5; ++i ) {
		c.arg[0] = blocks[i];
		c.arg[1] = i;
		clearCommandBuffer();
		SendCommand(&c);
		if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
			PrintAndLog("Error occurred, device did not respond during write operation.");
			return -1;
		}
	}
	return 0;
}
Пример #11
0
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){
	*key = 0;
	UsbCommand c = {CMD_MIFARE_CHKKEYS, { (blockNo | (keyType<<8)), clear_trace, keycnt}};
	memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
	clearCommandBuffer();
	SendCommand(&c);
	UsbCommand resp;
	if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) return 1;
	if ((resp.arg[0] & 0xff) != 0x01) return 2;
	*key = bytes_to_num(resp.d.asBytes, 6);
	return 0;
}
Пример #12
0
int CmdStatus(const char *Cmd)
{
	uint8_t speed_test_buffer[USB_CMD_DATA_SIZE];
	sample_buf = speed_test_buffer;

	clearCommandBuffer();
	UsbCommand c = {CMD_STATUS};
	SendCommand(&c);
	if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) {
		PrintAndLog("Status command failed. USB Speed Test timed out");
	}
	return 0;
}
Пример #13
0
int CmdPing(const char *Cmd)
{
	clearCommandBuffer();
	UsbCommand resp;
	UsbCommand c = {CMD_PING};
	SendCommand(&c);
	if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
		PrintAndLog("Ping successfull");
	}else{
		PrintAndLog("Ping failed");
	}
	return 0;
}
Пример #14
0
int CmdLegicSave(const char *Cmd) {
	int requested = 1024;
	int offset = 0;
	int delivered = 0;
	char filename[FILE_PATH_SIZE];
	uint8_t got[1024] = {0x00};

	sscanf(Cmd, " %s %i %i", filename, &requested, &offset);

	/* If no length given save entire legic read buffer */
	/* round up to nearest 8 bytes so the saved data can be used with legicload */
	if (requested == 0)
		requested = 1024;

	if (requested % 8 != 0) {
		int remainder = requested % 8;
		requested = requested + 8 - remainder;
	}

	if (offset + requested > sizeof(got)) {
		PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 1024");
		return 0;
	}

	GetFromBigBuf(got, requested, offset);
	if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){
		PrintAndLog("Command execute timeout");	
		return 1;
	}

	FILE *f = fopen(filename, "w");
	if(!f) {
		PrintAndLog("couldn't open '%s'", Cmd+1);
		return -1;
	}
	
	for (int j = 0; j < requested; j += 8) {
		fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
			got[j+0], got[j+1], got[j+2], got[j+3],
			got[j+4], got[j+5],	got[j+6], got[j+7]
		);
		delivered += 8;
		if (delivered >= requested) break;
	}

	fclose(f);
	PrintAndLog("saved %u samples", delivered);
	return 0;
}
Пример #15
0
int CmdLFPCF7931Read(const char *Cmd) {

    uint8_t ctmp = param_getchar(Cmd, 0);
    if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();

    UsbCommand resp;
    UsbCommand c = {CMD_PCF7931_READ, {0, 0, 0}};
    clearCommandBuffer();
    SendCommand(&c);
    if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
        PrintAndLog("command execution time out");
        return 1;
    }
    return 0;
}
Пример #16
0
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
	uint8_t isOK = 0;
	UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};	
	clearCommandBuffer();
	SendCommand(&c);
	UsbCommand resp;
	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
		isOK  = resp.arg[0] & 0xff;
		memcpy(data, resp.d.asBytes, 16);
		if (!isOK) return 2;
	} else {
		PrintAndLog("Command execute timeout");
		return 1;
	}
	return 0;
}
Пример #17
0
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {

	uint8_t isOK = 0;
	UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
	memcpy(c.d.asBytes, data, 16); 
	SendCommand(&c);

	UsbCommand resp;
	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
		isOK  = resp.arg[0] & 0xff;
		if (uid != NULL) 
			memcpy(uid, resp.d.asBytes, 4);
		if (!isOK) 
			return 2;
	} else {
		PrintAndLog("Command execute timeout");
		return 1;
	}
	return 0;
}
Пример #18
0
/**
 * @brief The following params expected:
 * uint32_t cmd
 * size_t ms_timeout
 * @param L
 * @return
 */
static int l_WaitForResponseTimeout(lua_State *L) {

    uint32_t cmd = 0;
    size_t ms_timeout = -1;

    //Check number of arguments
    int n = lua_gettop(L);
    if(n == 0)
    {
        //signal error by returning Nil, errorstring
        lua_pushnil(L);
        lua_pushstring(L,"You need to supply at least command to wait for");
        return 2; // two return values
    }
    if(n >= 1)
    {
        //pop cmd
        cmd = luaL_checkunsigned(L,1);
    }
    if(n >= 2)
    {
        //Did the user send a timeout ?
        //Check if the current top of stack is an integer
        ms_timeout = luaL_checkunsigned(L,2);
        //printf("Timeout set to %dms\n" , (int) ms_timeout);
    }

    UsbCommand response;

    if(WaitForResponseTimeout(cmd, &response, ms_timeout))
    {
        //Push it as a string
        lua_pushlstring(L,(const char *)&response, sizeof(UsbCommand));

        return 1;// return 1 to signal one return value
    } else {
        //Push a Nil instead
        lua_pushnil(L);
        return 1;// one return value
    }
}
Пример #19
0
int CmdVersion(const char *Cmd)
{

	clearCommandBuffer();
	UsbCommand c = {CMD_VERSION};
	static UsbCommand resp = {0, {0, 0, 0}};

	if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available
		SendCommand(&c);
		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
			PrintAndLog("Prox/RFID mark3 RFID instrument");
			PrintAndLog((char*)resp.d.asBytes);
			lookupChipID(resp.arg[0], resp.arg[1]);
		}
	} else {
		PrintAndLog("[[[ Cached information ]]]\n");
		PrintAndLog("Prox/RFID mark3 RFID instrument");
		PrintAndLog((char*)resp.d.asBytes);
		lookupChipID(resp.arg[0], resp.arg[1]);
		PrintAndLog("");
	}
	return 0;
}
Пример #20
0
int CmdHF14AMfDESAuth(const char *Cmd){
        
    uint8_t blockNo = 0;
    //keyNo=0;
    uint32_t cuid=0;
    uint8_t reply[16];
    //DES_cblock r1_b1;
    uint8_t b1[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t b2[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    DES_cblock nr,  b0, r1, r0;
    
    
    uint8_t key[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    //DES_cblock iv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    DES_key_schedule ks1;
    DES_cblock key1;

    if (strlen(Cmd)<1) {
        PrintAndLog("Usage:  hf desfire des-auth k <key number>");
        PrintAndLog("        sample: hf desfire des-auth k 0");
        return 0;
    } 
    
    //Change key to user defined one
    
    memcpy(key1,key,8);
    //memcpy(key2,key+8,8);
    DES_set_key((DES_cblock *)key1,&ks1);
    //DES_set_key((DES_cblock *)key2,&ks2);
        
    //Auth1
    UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}};
    SendCommand(&c);
    UsbCommand resp;
    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
        uint8_t isOK  = resp.arg[0] & 0xff;
	        cuid  = resp.arg[1];
        uint8_t * data= resp.d.asBytes;

         if (isOK){
             PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,8));
             memcpy(b0,data+2,8);
	}
    } else {
        PrintAndLog("Command execute timeout");
    }
       
    //Do crypto magic
    DES_random_key(&nr);
    //b1=dec(nr)
    //r0=dec(b0)
    DES_ecb_encrypt(&nr,&b1,&ks1,0);
    DES_ecb_encrypt(&b0,&r0,&ks1,0);
    //PrintAndLog("b1:%s",sprint_hex(b1, 8));
    PrintAndLog("r0:%s",sprint_hex(r0, 8));
    //r1=rol(r0)
    memcpy(r1,r0,8);
    rol(r1,8);
    PrintAndLog("r1:%s",sprint_hex(r1, 8));
    for(int i=0;i<8;i++){   
      b2[i]=(r1[i] ^ b1[i]);
    }
    DES_ecb_encrypt(&b2,&b2,&ks1,0);
    //PrintAndLog("b1:%s",sprint_hex(b1, 8));
    PrintAndLog("b2:%s",sprint_hex(b2, 8));

    //Auth2
    UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}};
    memcpy(reply,b1,8);
    memcpy(reply+8,b2,8);
    memcpy(d.d.asBytes,reply, 16);
    SendCommand(&d);

    UsbCommand respb;
    if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
        uint8_t  isOK  = respb.arg[0] & 0xff;
        uint8_t * data2= respb.d.asBytes;

        if (isOK){
            PrintAndLog("b3:%s", sprint_hex(data2+2, 8));
	}
                 
    } else {
        PrintAndLog("Command execute timeout");
    } 
    return 1;
}
Пример #21
0
UsbCommand * WaitForResponse(uint32_t response_type)
{
	return WaitForResponseTimeout(response_type, -1);
}
Пример #22
0
int CmdHF15Raw(const char *Cmd) {

	char cmdp = param_getchar(Cmd, 0);
	if (strlen(Cmd)<3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw();

	UsbCommand resp;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	int reply = 1, fast = 1, i = 0;
	bool crc = false;
	char buf[5] = "";
	uint8_t data[100];
	uint32_t datalen = 0, temp;
	
	// strip
	while (*Cmd==' ' || *Cmd=='\t') Cmd++;
	
	while (Cmd[i]!='\0') {
		if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
		if (Cmd[i]=='-') {
			switch (Cmd[i+1]) {
				case 'r': 
				case 'R': 
					reply = 0;
					break;
				case '2':
					fast = 0;
					break;
				case 'c':
				case 'C':				
					crc = true;
					break;
				default:
					PrintAndLogEx(WARNING, "Invalid option");
					return 0;
			}
			i+=2;
			continue;
		}
		if ((Cmd[i]>='0' && Cmd[i]<='9') ||
		    (Cmd[i]>='a' && Cmd[i]<='f') ||
		    (Cmd[i]>='A' && Cmd[i]<='F') ) {
		    buf[strlen(buf)+1] = 0;
		    buf[strlen(buf)] = Cmd[i];
		    i++;
		    
		    if (strlen(buf) >= 2) {
		    	sscanf(buf, "%x", &temp);
		    	data[datalen] = (uint8_t)(temp & 0xff);
		    	datalen++;
		    	*buf = 0;
		    }
		    continue;
		}
		PrintAndLogEx(WARNING, "Invalid char on input");
		return 0;
	}
	
	if (crc) {
		AddCrc(data, datalen);
		datalen += 2;
	}
	
	c.arg[0] = datalen;
	c.arg[1] = fast;
	c.arg[2] = reply;
	memcpy(c.d.asBytes, data, datalen);

	clearCommandBuffer();	
	SendCommand(&c);
	
	if (reply) {
		if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
			uint8_t len = resp.arg[0];
			PrintAndLogEx(NORMAL, "received %i octets", len);
			PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.d.asBytes, len) );
		} else {
			PrintAndLogEx(WARNING, "timeout while waiting for reply.");
		}		
	}
	return 0;
}
Пример #23
0
//EV1
// Reader 2 Card : 02AA, key (1 byte), CRC1 CRC2 ; auth
// Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2
// Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2
// Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success
int CmdHF14AMfAESAuth(const char *Cmd){
        
    uint8_t blockNo = 0;
    //keyNo=0;
    uint32_t cuid=0;
    uint8_t reply[32];
    //DES_cblock r1_b1;
    //unsigned char * b1, b2, nr, b0, r0, r1;
    
    uint8_t b1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t b2[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t nr[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t b0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t r0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t r1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    //
    uint8_t key[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uint8_t iv[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    AES_KEY key_e;
    AES_KEY key_d;

    if (strlen(Cmd)<1) {
        PrintAndLog("Usage:  hf desfire aes-auth k <key number>");
        PrintAndLog("        sample: hf desfire aes-auth k 0");
        return 0;
    } 
    
    //Change key to user defined one
    //
    // int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);
     //int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);
	//
    //memcpy(key1,key,16);
    //memcpy(key2,key+8,8);
    AES_set_encrypt_key(key,128,&key_e);
    AES_set_decrypt_key(key,128,&key_d);
        
    //Auth1
    UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}};
    SendCommand(&c);
    UsbCommand resp;
    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
        uint8_t isOK  = resp.arg[0] & 0xff;
	        cuid  = resp.arg[1];
        uint8_t * data= resp.d.asBytes;

         if (isOK){
             PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,16));
             memcpy(b0,data+2,16);
	}
    } else {
        PrintAndLog("Command execute timeout");
    }
    //
    // void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
	//size_t length, const AES_KEY *key,
	//unsigned char *ivec, const int enc);
    
   //Do crypto magic
    //DES_random_key(&nr);
    //b1=dec(nr)
    //r0=dec(b0)
    //AES_cbc_encrypt(&nr,&b1,16,&key,0);
    AES_cbc_encrypt(&b0,&r0,16,&key_d,iv,0);
    //PrintAndLog("b1:%s",sprint_hex(b1, 8));
    PrintAndLog("r0:%s",sprint_hex(r0, 16));
    //r1=rol(r0)
    memcpy(r1,r0,16);
    rol(r1,8);
    PrintAndLog("r1:%s",sprint_hex(r1, 16));
    for(int i=0;i<16;i++){
      b1[i]=(nr[i] ^ b0[i]);
      b2[i]=(r1[i] ^ b1[i]);
    }
    PrintAndLog("nr:%s",sprint_hex(nr, 16));
    AES_cbc_encrypt(&b1,&b1,16,&key_e,iv,1);
    AES_cbc_encrypt(&b2,&b2,16,&key_e,iv,1);
    PrintAndLog("b1:%s",sprint_hex(b1, 16));
    PrintAndLog("b2:%s",sprint_hex(b2, 16));

    //Auth2
    UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}};
    memcpy(reply,b1,16);
    memcpy(reply+16,b2,16);
    memcpy(d.d.asBytes,reply, 32);
    SendCommand(&d);

    UsbCommand respb;
    if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
        uint8_t  isOK  = respb.arg[0] & 0xff;
        uint8_t * data2= respb.d.asBytes;

        if (isOK){
            PrintAndLog("b3:%s", sprint_hex(data2+2, 16));
	}
                 
    } else {
        PrintAndLog("Command execute timeout");
    } 
    return 1;
}
Пример #24
0
/**
 * Commandline handling: HF15 CMD SYSINFO
 * get system information from tag/VICC
 */
int CmdHF15Info(const char *Cmd) {

	char cmdp = param_getchar(Cmd, 0);
	if (strlen(Cmd)<1 || cmdp == 'h' || cmdp == 'H') return usage_15_info();

	UsbCommand resp;
	uint8_t *recv;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	uint8_t *req = c.d.asBytes;
	char cmdbuf[100];
	char *cmd = cmdbuf;
	memset(cmdbuf, 0, sizeof(cmdbuf));
	
	strncpy(cmd, Cmd, 99);
	
	if ( !prepareHF15Cmd(&cmd, &c, ISO15_CMD_SYSINFO) )
		return 0;

	AddCrc(req,  c.arg[0]);
	c.arg[0] += 2;

	//PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(c.d.asBytes, reqlen) ); 
	
	clearCommandBuffer();
	SendCommand(&c);

	if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
		PrintAndLogEx(NORMAL, "iso15693 card select failed");
		return 1;
	}
	
	uint32_t status = resp.arg[0];
	
	if ( status < 2 ) {
		PrintAndLogEx(NORMAL, "iso15693 card doesn't answer to systeminfo command");
		return 1;		
	}
	
	recv = resp.d.asBytes;	
	
	if ( recv[0] & ISO15_RES_ERROR ) {
		PrintAndLogEx(NORMAL, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); 
		return 3;
	}
	
	PrintAndLogEx(NORMAL, "  UID  : %s", sprintUID(NULL, recv+2));
	PrintAndLogEx(NORMAL, "  TYPE : %s", getTagInfo_15(recv+2));
	PrintAndLogEx(NORMAL, "  SYSINFO : %s", sprint_hex(recv, status-2));

	// DSFID
	if (recv[1] & 0x01) 
		PrintAndLogEx(NORMAL, "     - DSFID supported        [0x%02X]", recv[10]);
	else 
		PrintAndLogEx(NORMAL, "     - DSFID not supported");
	
	// AFI
	if (recv[1] & 0x02) 
		PrintAndLogEx(NORMAL, "     - AFI   supported        [0x%02X]", recv[11]);
	else 
		PrintAndLogEx(NORMAL, "     - AFI   not supported");

	// IC reference
	if (recv[1] & 0x08) 
		PrintAndLogEx(NORMAL, "     - IC reference supported [0x%02X]", recv[14]);
	else 
		PrintAndLogEx(NORMAL, "     - IC reference not supported");

	// memory 
	if (recv[1] & 0x04) {
		PrintAndLogEx(NORMAL, "     - Tag provides info on memory layout (vendor dependent)");
		uint8_t blocks = recv[12]+1;
		uint8_t size = (recv[13] & 0x1F);
		PrintAndLogEx(NORMAL, "           %u (or %u) bytes/blocks x %u blocks", size+1, size, blocks );
	} else {
		PrintAndLogEx(NORMAL, "     - Tag does not provide information on memory layout");
	}
	PrintAndLogEx(NORMAL, "\n");
	return 0;
}
Пример #25
0
// Reads all memory pages
// need to write to file
int CmdHF15Dump(const char*Cmd) {
	
	uint8_t fileNameLen = 0;
	char filename[FILE_PATH_SIZE] = {0};
	char * fptr = filename;
	bool errors = false;
	uint8_t cmdp = 0;
	uint8_t uid[8] = {0,0,0,0,0,0,0,0};	
	
	while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
		switch(param_getchar(Cmd, cmdp)) {
		case 'h':
		case 'H':
			return usage_15_dump();
		case 'f':
		case 'F':
			fileNameLen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); 
			cmdp += 2;
			break;
		default:
			PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
			errors = true;
			break;
		}
	}

	//Validations
	if (errors) return usage_15_dump();
	
	if (fileNameLen < 1) {

		PrintAndLogEx(INFO, "Using UID as filename");

		if (!getUID(uid)) {
			PrintAndLogEx(WARNING, "No tag found.");
			return 1;
		}
		
		fptr += sprintf(fptr, "hf-15-"); 
		FillFileNameByUID(fptr,uid,"-dump",sizeof(uid));

	}	
	// detect blocksize from card :)
	
	PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprintUID(NULL, uid));

	int blocknum = 0;
	uint8_t *recv = NULL;

	// memory.
	t15memory mem[256];
	
	uint8_t data[256*4] = {0};
	memset(data, 0, sizeof(data));

	UsbCommand resp;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	uint8_t *req = c.d.asBytes;
	req[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
	req[1] = ISO15_CMD_READ;

	// copy uid to read command
	memcpy(req+2, uid, sizeof(uid));
	
	for (int retry = 0; retry < 5; retry++) {
	
		req[10] = blocknum;
		AddCrc(req, 11);
		c.arg[0] = 13;
	
		clearCommandBuffer();
		SendCommand(&c);
				
		if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {

			uint8_t len = resp.arg[0];
			if ( len < 2 ) {
				PrintAndLogEx(FAILED, "iso15693 card select failed");
				continue;		
			}
			
			recv = resp.d.asBytes;
			
			if ( !CheckCrc(recv, len) ) {
				PrintAndLogEx(FAILED, "crc fail");
				continue;
			}

			if (recv[0] & ISO15_RES_ERROR) {
				PrintAndLogEx(FAILED, "Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) ); 
				break;
			}
								
			mem[blocknum].lock = resp.d.asBytes[0];
			memcpy(mem[blocknum].block, resp.d.asBytes + 1, 4);					
			memcpy(data + (blocknum * 4), resp.d.asBytes + 1, 4);
			
			retry = 0;
			blocknum++;
			
			printf("."); fflush(stdout);
		} 
	}
	PrintAndLogEx(NORMAL, "\n");

	PrintAndLogEx(NORMAL, "block#   | data         |lck| ascii");
	PrintAndLogEx(NORMAL, "---------+--------------+---+----------");	
	for (int i = 0; i < blocknum; i++) {
		PrintAndLogEx(NORMAL, "%3d/0x%02X | %s | %d | %s", i, i, sprint_hex(mem[i].block, 4 ), mem[i].lock, sprint_ascii(mem[i].block, 4) );
	}
	PrintAndLogEx(NORMAL, "\n");

	size_t datalen = blocknum * 4;
	saveFileEML(filename, "eml", data, datalen, 4);	
	saveFile(filename, "bin", data, datalen);
	return 0;
}
Пример #26
0
/*
 *  Output BigBuf and deobfuscate LEGIC RF tag data.
 *  This is based on information given in the talk held
 *  by Henryk Ploetz and Karsten Nohl at 26c3
 */
int CmdLegicDecode(const char *Cmd) {
	// Index for the bytearray.
	int i = 0;
	int k = 0, segmentNum;
	int segment_len = 0;
	int segment_flag = 0;
	uint8_t stamp_len = 0;
	int crc = 0;
	int wrp = 0;
	int wrc = 0;
	uint8_t data_buf[1024]; // receiver buffer,  should be 1024..
	char token_type[4];

	// download EML memory, where the "legic read" command puts the data.
	GetEMLFromBigBuf(data_buf, sizeof(data_buf), 0);
	if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){
		PrintAndLog("Command execute timeout");
		return 1;
	}
	
	// Output CDF System area (9 bytes) plus remaining header area (12 bytes)
	crc = data_buf[4];
	uint32_t calc_crc =  CRC8Legic(data_buf, 4);	
	
	PrintAndLog("\nCDF: System Area");
	PrintAndLog("------------------------------------------------------");
	PrintAndLog("MCD: %02x, MSN: %02x %02x %02x, MCC: %02x %s",
		data_buf[0],
		data_buf[1],
		data_buf[2],
		data_buf[3],
		data_buf[4],
		(calc_crc == crc) ? "OK":"Fail" 
	);
 
	switch (data_buf[5] & 0x7f) {
		case 0x00 ... 0x2f:
			strncpy(token_type, "IAM",sizeof(token_type));
			break;
		case 0x30 ... 0x6f:
			strncpy(token_type, "SAM",sizeof(token_type));
			break;
		case 0x70 ... 0x7f:
			strncpy(token_type, "GAM",sizeof(token_type));
			break;
		default:
			strncpy(token_type, "???",sizeof(token_type));
			break;
	}

	stamp_len = 0xfc - data_buf[6];

	PrintAndLog("DCF: %02x %02x, Token Type=%s (OLE=%01u), Stamp len=%02u",
		data_buf[5],
		data_buf[6],
		token_type,
		(data_buf[5]&0x80)>>7,
		stamp_len
	);

	PrintAndLog("WRP=%02u, WRC=%01u, RD=%01u, raw=%02x, SSC=%02x",
		data_buf[7]&0x0f,
		(data_buf[7]&0x70)>>4,
		(data_buf[7]&0x80)>>7,
		data_buf[7],
		data_buf[8]
	);

	PrintAndLog("Remaining Header Area");
	PrintAndLog("%s", sprint_hex(data_buf+9, 13));
	
	uint8_t segCrcBytes[8] = {0x00};
	uint32_t segCalcCRC = 0;
	uint32_t segCRC = 0;

	// see if user area is xored or just zeros.
	int numOfZeros = 0;
	for (int index=22; index < 256; ++index){
		if ( data_buf[index] == 0x00 )
			++numOfZeros;
	}
	// if possible zeros is less then 60%, lets assume data is xored
	// 256  - 22 (header) = 234
	// 1024 - 22 (header) = 1002
	int isXored = (numOfZeros*100/stamp_len) < 50;
	PrintAndLog("is data xored?  %d  ( %d %)", isXored, (numOfZeros*100/stamp_len));

	print_hex_break( data_buf, 33, 16);
	
	return 0;
	
	PrintAndLog("\nADF: User Area");
	PrintAndLog("------------------------------------------------------");
	i = 22;  
	// 64 potential segements
	// how to detect there is no segments?!?
	for ( segmentNum=0; segmentNum<64; segmentNum++ ) {
		segment_len = ((data_buf[i+1]^crc)&0x0f) * 256 + (data_buf[i]^crc);
		segment_flag = ((data_buf[i+1]^crc)&0xf0)>>4;

		wrp = (data_buf[i+2]^crc);
		wrc = ((data_buf[i+3]^crc)&0x70)>>4;

		bool hasWRC = (wrc > 0);
		bool hasWRP = (wrp > wrc);
		int wrp_len = (wrp - wrc);
		int remain_seg_payload_len = (segment_len - wrp - 5);
		
		// validate segment-crc
		segCrcBytes[0]=data_buf[0];			//uid0
		segCrcBytes[1]=data_buf[1];			//uid1
		segCrcBytes[2]=data_buf[2];			//uid2
		segCrcBytes[3]=data_buf[3];			//uid3
		segCrcBytes[4]=(data_buf[i]^crc); 	//hdr0
		segCrcBytes[5]=(data_buf[i+1]^crc); //hdr1
		segCrcBytes[6]=(data_buf[i+2]^crc); //hdr2
		segCrcBytes[7]=(data_buf[i+3]^crc); //hdr3

		segCalcCRC = CRC8Legic(segCrcBytes, 8);
		segCRC = data_buf[i+4]^crc;

		PrintAndLog("Segment %02u \nraw header | 0x%02X 0x%02X 0x%02X 0x%02X \nSegment len: %u,  Flag: 0x%X (valid:%01u, last:%01u), WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)",
			segmentNum,
			data_buf[i]^crc,
			data_buf[i+1]^crc,
			data_buf[i+2]^crc,
			data_buf[i+3]^crc,
			segment_len, 
			segment_flag,
			(segment_flag & 0x4) >> 2,
			(segment_flag & 0x8) >> 3,
			wrp,
			wrc,
			((data_buf[i+3]^crc) & 0x80) >> 7,
			segCRC,
			( segCRC == segCalcCRC ) ? "OK" : "fail"
		);

		i += 5;
    
		if ( hasWRC ) {
			PrintAndLog("WRC protected area:   (I %d | K %d| WRC %d)", i, k, wrc);
			PrintAndLog("\nrow  | data");
			PrintAndLog("-----+------------------------------------------------");
			// de-xor?  if not zero, assume it needs xoring.
			if ( isXored) {
				for ( k=i; k < wrc; ++k)
					data_buf[k] ^= crc;
			}
			print_hex_break( data_buf+i, wrc, 16);
			
			i += wrc;
		}
    
		if ( hasWRP ) {
			PrintAndLog("Remaining write protected area:  (I %d | K %d | WRC %d | WRP %d  WRP_LEN %d)",i, k, wrc, wrp, wrp_len);
			PrintAndLog("\nrow  | data");
			PrintAndLog("-----+------------------------------------------------");

			if (isXored) {
				for (k=i; k < wrp_len; ++k)
					data_buf[k] ^= crc;
			}
			
			print_hex_break( data_buf+i, wrp_len, 16);
			
			i += wrp_len;
			
			// does this one work?
			if( wrp_len == 8 )
				PrintAndLog("Card ID: %2X%02X%02X", data_buf[i-4]^crc, data_buf[i-3]^crc, data_buf[i-2]^crc);			
		}
    
		PrintAndLog("Remaining segment payload:  (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len);
		PrintAndLog("\nrow  | data");
		PrintAndLog("-----+------------------------------------------------");
		if ( isXored ) {
			for ( k=i; k < remain_seg_payload_len; ++k)
				data_buf[k] ^= crc;
		}
		
		print_hex_break( data_buf+i, remain_seg_payload_len, 16);
    
		i += remain_seg_payload_len;
		
		PrintAndLog("-----+------------------------------------------------\n");

		// end with last segment
		if (segment_flag & 0x8) return 0;

	} // end for loop
	return 0;
}
Пример #27
0
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) 
{
	uint16_t i;
	uint32_t uid;
	UsbCommand resp;

	StateList_t statelists[2];
	struct Crypto1State *p1, *p2, *p3, *p4;
	
	// flush queue
	WaitForResponseTimeout(CMD_ACK,NULL,100);
	
	UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}};
	memcpy(c.d.asBytes, key, 6);
	SendCommand(&c);

	if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
		return -1;
	}

	if (resp.arg[0]) {
		return resp.arg[0];  // error during nested
	}
		
			memcpy(&uid, resp.d.asBytes, 4);
	PrintAndLog("uid:%08x trgbl=%d trgkey=%x", uid, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8);
			
			for (i = 0; i < 2; i++) {
				statelists[i].blockNo = resp.arg[2] & 0xff;
				statelists[i].keyType = (resp.arg[2] >> 8) & 0xff;
				statelists[i].uid = uid;
				memcpy(&statelists[i].nt,  (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4);
				memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4);
			}
	
	// calc keys
	
	pthread_t thread_id[2];
		
	// create and run worker threads
	for (i = 0; i < 2; i++) {
		pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]);
	}
	
	// wait for threads to terminate:
	for (i = 0; i < 2; i++) {
		pthread_join(thread_id[i], (void*)&statelists[i].head.slhead);
	}


	// the first 16 Bits of the cryptostate already contain part of our key.
	// Create the intersection of the two lists based on these 16 Bits and
	// roll back the cryptostate
	p1 = p3 = statelists[0].head.slhead; 
	p2 = p4 = statelists[1].head.slhead;
	while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) {
		if (Compare16Bits(p1, p2) == 0) {
			struct Crypto1State savestate, *savep = &savestate;
			savestate = *p1;
			while(Compare16Bits(p1, savep) == 0 && p1 <= statelists[0].tail.sltail) {
				*p3 = *p1;
				lfsr_rollback_word(p3, statelists[0].nt ^ statelists[0].uid, 0);
				p3++;
				p1++;
			}
			savestate = *p2;
			while(Compare16Bits(p2, savep) == 0 && p2 <= statelists[1].tail.sltail) {
				*p4 = *p2;
				lfsr_rollback_word(p4, statelists[1].nt ^ statelists[1].uid, 0);
				p4++;
				p2++;
			}
		}
		else {
			while (Compare16Bits(p1, p2) == -1) p1++;
			while (Compare16Bits(p1, p2) == 1) p2++;
		}
	}
	p3->even = 0; p3->odd = 0;
	p4->even = 0; p4->odd = 0;
	statelists[0].len = p3 - statelists[0].head.slhead;
	statelists[1].len = p4 - statelists[1].head.slhead;
	statelists[0].tail.sltail=--p3;
	statelists[1].tail.sltail=--p4;

	// the statelists now contain possible keys. The key we are searching for must be in the
	// intersection of both lists. Create the intersection:
	qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compar_int);
	qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compar_int);

	uint64_t *p5, *p6, *p7;
	p5 = p7 = statelists[0].head.keyhead; 
	p6 = statelists[1].head.keyhead;
	while (p5 <= statelists[0].tail.keytail && p6 <= statelists[1].tail.keytail) {
		if (compar_int(p5, p6) == 0) {
			*p7++ = *p5++;
			p6++;
		}
		else {
			while (compar_int(p5, p6) == -1) p5++;
			while (compar_int(p5, p6) == 1) p6++;
		}
	}
	statelists[0].len = p7 - statelists[0].head.keyhead;
	statelists[0].tail.keytail=--p7;

	memset(resultKey, 0, 6);
	// The list may still contain several key candidates. Test each of them with mfCheckKeys
	for (i = 0; i < statelists[0].len; i++) {
		uint8_t keyBlock[6];
		uint64_t key64;
		crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);
		num_to_bytes(key64, 6, keyBlock);
		key64 = 0;
		if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) {
			num_to_bytes(key64, 6, resultKey);
			break;
		}
	}
	
	free(statelists[0].head.slhead);
	free(statelists[1].head.slhead);
	
	return 0;
}
Пример #28
0
// Reads all memory pages
int CmdHF15DumpMem(const char*Cmd) {
	UsbCommand resp;
	uint8_t uid[8];	
	uint8_t *recv=NULL;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	uint8_t *req=c.d.asBytes;
	int reqlen=0;
	int blocknum=0;
	char output[80];
		
	if (!getUID(uid)) {
		PrintAndLog("No Tag found.");
		return 0;
	}
	
	PrintAndLog("Reading memory from tag UID=%s",sprintUID(NULL,uid));
	PrintAndLog("Tag Info: %s",getTagInfo(uid));

	for (int retry=0; retry<5; retry++) {
		
		req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | 
		        ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
		req[1]=ISO15_CMD_READ;
		memcpy(&req[2],uid,8);
		req[10]=blocknum;
		reqlen=AddCrc(req,11);
		c.arg[0]=reqlen;
	
		SendCommand(&c);
		
		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
			recv = resp.d.asBytes;
			if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
				if (!(recv[0] & ISO15_RES_ERROR)) {
					retry=0;
					*output=0; // reset outputstring
					sprintf(output, "Block %02x   ",blocknum);
					for ( int i=1; i<resp.arg[0]-2; i++) { // data in hex
						sprintf(output+strlen(output),"%02X ",recv[i]);
					}					
					strcat(output,"   "); 
					for ( int i=1; i<resp.arg[0]-2; i++) { // data in cleaned ascii
						sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');					
					}					
					PrintAndLog("%s",output);	
					blocknum++;
					// PrintAndLog("bn=%i",blocknum);
				} else {
					PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
					return 0;
				}
			} // else PrintAndLog("crc");
		} // else PrintAndLog("r null");
	} // retry
  // TODO: need fix
//	if (resp.arg[0]<3)
//		PrintAndLog("Lost Connection");
//	else if (ISO15_CRC_CHECK!=Crc(resp.d.asBytes,resp.arg[0]))
//		PrintAndLog("CRC Failed");
//	else 
//		PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
	return 0;
}
Пример #29
0
int CmdHF15CmdRaw (const char *cmd) {
	UsbCommand resp;
	uint8_t *recv;
	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
	int reply=1;
	int fast=1;	
	int crc=0;
	char buf[5]="";
	int i=0;
	uint8_t data[100];
	unsigned int datalen=0, temp;
	char *hexout;

	
	if (strlen(cmd)<3) {
		PrintAndLog("Usage: hf 15 cmd raw  [-r] [-2] [-c] <0A 0B 0C ... hex>");
		PrintAndLog("       -r    do not read response");
		PrintAndLog("       -2    use slower '1 out of 256' mode");
		PrintAndLog("       -c	  calculate and append CRC");
		PrintAndLog(" Tip: turn on debugging for verbose output");		
		return 0;	
	}

	// strip
	while (*cmd==' ' || *cmd=='\t') cmd++;
	
	while (cmd[i]!='\0') {
		if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
		if (cmd[i]=='-') {
			switch (cmd[i+1]) {
				case 'r': 
				case 'R': 
					reply=0;
					break;
				case '2':
					fast=0;
					break;
				case 'c':
				case 'C':				
					crc=1;
					break;
				default:
					PrintAndLog("Invalid option");
					return 0;
			}
			i+=2;
			continue;
		}
		if ((cmd[i]>='0' && cmd[i]<='9') ||
		    (cmd[i]>='a' && cmd[i]<='f') ||
		    (cmd[i]>='A' && cmd[i]<='F') ) {
		    buf[strlen(buf)+1]=0;
		    buf[strlen(buf)]=cmd[i];
		    i++;
		    
		    if (strlen(buf)>=2) {
		    	sscanf(buf,"%x",&temp);
		    	data[datalen]=(uint8_t)(temp & 0xff);
		    	datalen++;
		    	*buf=0;
		    }
		    continue;
		}
		PrintAndLog("Invalid char on input");
		return 0;
	}
	if (crc) datalen=AddCrc(data,datalen);
	
	c.arg[0]=datalen;
	c.arg[1]=fast;
	c.arg[2]=reply;
	memcpy(c.d.asBytes,data,datalen);
	
	SendCommand(&c);
	
	if (reply) {
		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
			recv = resp.d.asBytes;
			PrintAndLog("received %i octets",resp.arg[0]);
			hexout = (char *)malloc(resp.arg[0] * 3 + 1);
			if (hexout != NULL) {
				for (int i = 0; i < resp.arg[0]; i++) { // data in hex
					sprintf(&hexout[i * 3], "%02X ", recv[i]);
				}
				PrintAndLog("%s", hexout);
				free(hexout);
			}
		} else {
			PrintAndLog("timeout while waiting for reply.");
		}
		
	} // if reply
	return 0;
}
Пример #30
0
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
	return WaitForResponseTimeout(cmd,response,-1);
}