Esempio n. 1
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);
   }
}
Esempio n. 2
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
}
Esempio n. 3
0
/**
 * @brief l_foobar is a dummy function to test lua-integration with
 * @param L
 * @return
 */
static int l_foobar(lua_State *L)
{
    //Check number of arguments
    int n = lua_gettop(L);
    printf("foobar called with %d arguments" , n);
    lua_settop(L, 0);
    printf("Arguments discarded, stack now contains %d elements", lua_gettop(L));

    // todo: this is not used, where was it intended for?
    // UsbCommand response =  {CMD_MIFARE_READBL, {1337, 1338, 1339}};

    printf("Now returning a uint64_t as a string");
    uint64_t x = 0xDEADBEEF;
    uint8_t destination[8];
    num_to_bytes(x,sizeof(x),destination);
    lua_pushlstring(L,(const char *)&x,sizeof(x));
    lua_pushlstring(L,(const char *)destination,sizeof(destination));

    return 2;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
0
int CmdFdxDemod(const char *Cmd){

	//Differential Biphase / di-phase (inverted biphase)
	//get binary from ask wave
	if (!ASKbiphaseDemod("0 32 1 0", false)) {
		if (g_debugMode) PrintAndLog("DEBUG: Error - FDX-B ASKbiphaseDemod failed");
		return 0;
	}
	size_t size = DemodBufferLen;
	int preambleIndex = FDXBdemodBI(DemodBuffer, &size);
	if (preambleIndex < 0){
		if (g_debugMode){
			if (preambleIndex == -1)
				PrintAndLog("DEBUG: Error - FDX-B too few bits found");
			else if (preambleIndex == -2)
				PrintAndLog("DEBUG: Error - FDX-B preamble not found");
			else if (preambleIndex == -3)
				PrintAndLog("DEBUG: Error - FDX-B Size not correct: %d", size);
			else
				PrintAndLog("DEBUG: Error - FDX-B ans: %d", preambleIndex);
		}
		return 0;
	}

	// set and leave DemodBuffer intact
	setDemodBuf(DemodBuffer, 128, preambleIndex);
	setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex*g_DemodClock));

	uint8_t bits_no_spacer[117];
	memcpy(bits_no_spacer, DemodBuffer + 11, 117);

	// remove marker bits (1's every 9th digit after preamble) (pType = 2)
	size = removeParity(bits_no_spacer, 0, 9, 2, 117);
	if ( size != 104 ) {
		if (g_debugMode) PrintAndLog("DEBUG: Error removeParity:: %d", size);
		return 0;
	}

	//got a good demod
	uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(bits_no_spacer+32,6)) << 32) | bytebits_to_byteLSBF(bits_no_spacer,32);
	uint32_t countryCode = bytebits_to_byteLSBF(bits_no_spacer+38,10);
	uint8_t dataBlockBit = bits_no_spacer[48];
	uint32_t reservedCode = bytebits_to_byteLSBF(bits_no_spacer+49,14);
	uint8_t animalBit = bits_no_spacer[63];
	uint32_t crc16 = bytebits_to_byteLSBF(bits_no_spacer+64,16);
	uint32_t extended = bytebits_to_byteLSBF(bits_no_spacer+80,24);

	uint64_t rawid = ((uint64_t)bytebits_to_byte(bits_no_spacer,32)<<32) | bytebits_to_byte(bits_no_spacer+32,32);
	uint8_t raw[8];
	num_to_bytes(rawid, 8, raw);

	if (g_debugMode) {
		PrintAndLog("DEBUG: bits_no_spacer:\n%s",sprint_bin_break(bits_no_spacer,size,16));
		PrintAndLog("DEBUG: Start marker %d;   Size %d", preambleIndex, size);
		PrintAndLog("DEBUG: Raw ID Hex: %s", sprint_hex(raw,8));
	}

	uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
	PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:");
	PrintAndLog("Animal ID:     %04u-%012" PRIu64, countryCode, NationalCode);
	PrintAndLog("National Code: %012" PRIu64, NationalCode);
	PrintAndLog("CountryCode:   %04u", countryCode);
	PrintAndLog("Reserved Code: %u", reservedCode);
	PrintAndLog("Animal Tag:    %s", animalBit ? "True" : "False");
	PrintAndLog("Has Extended:  %s [0x%X]", dataBlockBit ? "True" : "False", extended);
	PrintAndLog("CRC:           0x%04X - 0x%04X - [%s]\n", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed");
	
	// set block 0 for later
	//g_DemodConfig = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT;
	return 1;
}