Example #1
0
uint64_t emlGetKey(int sectorNum, int keyType) {
	uint8_t key[6];
	uint8_t* emCARD = get_bigbufptr_emlcardmem();
	
	memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
	return bytes_to_num(key, 6);
}
Example #2
0
uint64_t emlGetKey(int sectorNum, int keyType) {
	uint8_t key[6];
	uint8_t* emCARD = BigBuf_get_EM_addr();
	
	memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
	return bytes_to_num(key, 6);
}
Example #3
0
static int l_nonce2key(lua_State *L) {

    size_t size;
    const char *p_uid = luaL_checklstring(L, 1, &size);
    if(size != 4)  return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size);

    const char *p_nt = luaL_checklstring(L, 2, &size);
    if(size != 4)  return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size);

    const char *p_nr = luaL_checklstring(L, 3, &size);
    if(size != 4)  return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size);

    const char *p_par_info = luaL_checklstring(L, 4, &size);
    if(size != 8)  return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size);

    const char *p_pks_info = luaL_checklstring(L, 5, &size);
    if(size != 8)  return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size);


    uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4);
    uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4);

    uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4);
    uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8);
    uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8);

    uint64_t key = 0;

    int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key);

    //Push the retval on the stack
    lua_pushinteger(L,retval);

    //Push the key onto the stack
    uint8_t dest_key[8];
    num_to_bytes(key,sizeof(dest_key),dest_key);

    //printf("Pushing to lua stack: %012"llx"\n",key);
    lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key));

    return 2; //Two return values
}
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;
}
Example #5
0
static void
init_offsets(uint64_t A, uint32_t a, uint32_t *offsets)
{
   int bit;
   uint64_t multiplier_base = bytes_to_num(num_to_bytes(MAX(A / a, a)));
   uint64_t multiplier_byte;

   for (bit = 0; bit < 8; bit++) {
      multiplier_byte = num_to_bytes((multiplier_base + ind_to_mod[bit]) * a);

      while (multiplier_byte < num_to_bytes(A))
         multiplier_byte += a;

      while (multiplier_byte - num_to_bytes(A) >= UINT16_MAX)
         multiplier_byte -= a;

      offsets[bit] = multiplier_byte - num_to_bytes(A);
   }
}
Example #6
0
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {

	if (traceCrypto1) 
		crypto1_destroy(traceCrypto1);

	traceCrypto1 = NULL;

	if (wantSaveToEmlFile) 
		loadTraceCard(tuid);
		
	traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];
	traceCard[5] = sak;
	memcpy(&traceCard[6], atqa, 2);
	traceCurBlock = 0;
	uid = bytes_to_num(tuid + 3, 4);
	
	traceState = TRACE_IDLE;

	return 0;
}
Example #7
0
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;
}
Example #8
0
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
	uint8_t data[64];

	if (traceState == TRACE_ERROR) return 1;
	if (len > 64) {
		traceState = TRACE_ERROR;
		return 1;
	}
	
	memcpy(data, data_src, len);
	if ((traceCrypto1) && ((traceState == TRACE_IDLE) || (traceState > TRACE_AUTH_OK))) {
		mf_crypto1_decrypt(traceCrypto1, data, len, 0);
		PrintAndLog("dec> %s", sprint_hex(data, len));
		AddLogHex(logHexFileName, "dec> ", data, len); 
	}
	
	switch (traceState) {
	case TRACE_IDLE: 
		// check packet crc16!
		if ((len >= 4) && (!CheckCrc14443(CRC_14443_A, data, len))) {
			PrintAndLog("dec> CRC ERROR!!!");
			AddLogLine(logHexFileName, "dec> ", "CRC ERROR!!!"); 
			traceState = TRACE_ERROR;  // do not decrypt the next commands
			return 1;
		}
		
		// AUTHENTICATION
		if ((len == 4) && ((data[0] == 0x60) || (data[0] == 0x61))) {
			traceState = TRACE_AUTH1;
			traceCurBlock = data[1];
			traceCurKey = data[0] == 60 ? 1:0;
			return 0;
		}

		// READ
		if ((len ==4) && ((data[0] == 0x30))) {
			traceState = TRACE_READ_DATA;
			traceCurBlock = data[1];
			return 0;
		}

		// WRITE
		if ((len ==4) && ((data[0] == 0xA0))) {
			traceState = TRACE_WRITE_OK;
			traceCurBlock = data[1];
			return 0;
		}

		// HALT
		if ((len ==4) && ((data[0] == 0x50) && (data[1] == 0x00))) {
			traceState = TRACE_ERROR;  // do not decrypt the next commands
			return 0;
		}
		
		return 0;
	break;
	
	case TRACE_READ_DATA: 
		if (len == 18) {
			traceState = TRACE_IDLE;

			if (isBlockTrailer(traceCurBlock)) {
				memcpy(traceCard + traceCurBlock * 16 + 6, data + 6, 4);
			} else {
				memcpy(traceCard + traceCurBlock * 16, data, 16);
			}
			if (wantSaveToEmlFile) saveTraceCard();
			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	case TRACE_WRITE_OK: 
		if ((len == 1) && (data[0] == 0x0a)) {
			traceState = TRACE_WRITE_DATA;

			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	case TRACE_WRITE_DATA: 
		if (len == 18) {
			traceState = TRACE_IDLE;

			memcpy(traceCard + traceCurBlock * 16, data, 16);
			if (wantSaveToEmlFile) saveTraceCard();
			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	case TRACE_AUTH1: 
		if (len == 4) {
			traceState = TRACE_AUTH2;
			nt = bytes_to_num(data, 4);
			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	case TRACE_AUTH2: 
		if (len == 8) {
			traceState = TRACE_AUTH_OK;

			nr_enc = bytes_to_num(data, 4);
			ar_enc = bytes_to_num(data + 4, 4);
			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	case TRACE_AUTH_OK: 
		if (len ==4) {
			traceState = TRACE_IDLE;

			at_enc = bytes_to_num(data, 4);
			
			//  decode key here)
			ks2 = ar_enc ^ prng_successor(nt, 64);
			ks3 = at_enc ^ prng_successor(nt, 96);
			revstate = lfsr_recovery64(ks2, ks3);
			lfsr_rollback_word(revstate, 0, 0);
			lfsr_rollback_word(revstate, 0, 0);
			lfsr_rollback_word(revstate, nr_enc, 1);
			lfsr_rollback_word(revstate, uid ^ nt, 0);

			crypto1_get_lfsr(revstate, &key);
			printf("Key: %012"llx"\n",key);
			AddLogUint64(logHexFileName, "key: ", key); 
			
			int blockShift = ((traceCurBlock & 0xFC) + 3) * 16;
			if (isBlockEmpty((traceCurBlock & 0xFC) + 3)) memcpy(traceCard + blockShift + 6, trailerAccessBytes, 4);
			
			if (traceCurKey) {
				num_to_bytes(key, 6, traceCard + blockShift + 10);
			} else {
				num_to_bytes(key, 6, traceCard + blockShift);
			}
			if (wantSaveToEmlFile) saveTraceCard();

			if (traceCrypto1) {
				crypto1_destroy(traceCrypto1);
			}
			
			// set cryptosystem state
			traceCrypto1 = lfsr_recovery64(ks2, ks3);
			
//	nt = crypto1_word(traceCrypto1, nt ^ uid, 1) ^ nt;

	/*	traceCrypto1 = crypto1_create(key); // key in lfsr
		crypto1_word(traceCrypto1, nt ^ uid, 0);
		crypto1_word(traceCrypto1, ar, 1);
		crypto1_word(traceCrypto1, 0, 0);
		crypto1_word(traceCrypto1, 0, 0);*/
	
			return 0;
		} else {
			traceState = TRACE_ERROR;
			return 1;
		}
	break;

	default: 
		traceState = TRACE_ERROR;
		return 1;
	}

	return 0;
}