From df007486f5119620e09930b030c29b62e67bb0b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 4 Aug 2016 21:51:26 +0200 Subject: [PATCH] ADD: @donwan581 select keytype for the darkside attack. --- CHANGELOG.md | 3 + armsrc/appmain.c | 2 +- armsrc/apps.h | 58 +++++++------- armsrc/iso14443a.c | 10 ++- armsrc/util.h | 3 + client/cmdanalyse.c | 11 ++- client/cmdanalyse.h | 1 + client/cmdhfmf.c | 188 +++++++++++++++++++++++++++++++------------- client/cmdhfmf.h | 6 +- client/util.h | 15 ++++ 10 files changed, 206 insertions(+), 91 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f65396..4f9da54c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - 'lf t55xx recoverpw' - adds a new password recovery using bitflips and partial flips if password write went bad. (alexgrin) + - 'hf legic' - added improved legic data mapping. (jason) + - 'hf mf mifare' - added possibility to target key A|B (douniwan5788) - 'analyse lcr' - added a new main command group, to help analysing bytes & bits & nibbles. (iceman) - 'lf nedap' - added identification of a NEDAP tag. (iceman) - 'lf viking clone' - fixed a bug. (iceman) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b069fb4b..14ecf28f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1100,7 +1100,7 @@ void UsbPacketReceived(uint8_t *packet, int len) EPA_PACE_Replay(c); break; case CMD_READER_MIFARE: - ReaderMifare(c->arg[0], c->arg[1]); + ReaderMifare(c->arg[0], c->arg[1], c->arg[2]); break; case CMD_MIFARE_READBL: MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); diff --git a/armsrc/apps.h b/armsrc/apps.h index 55cd61b3..b2e3083b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -98,14 +98,14 @@ void TurnReadLFOn(); void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode); void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode); -/// iso14443.h +/// iso14443b.h void SimulateIso14443bTag(uint32_t pupi); void AcquireRawAdcSamplesIso14443b(uint32_t parameter); void ReadSTMemoryIso14443b(uint8_t numofblocks); void RAMFUNC SnoopIso14443b(void); void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); -/// iso14443a.h +// iso14443a.h void RAMFUNC SniffIso14443a(uint8_t param); void SimulateIso14443aTag(int tagType, int flags, byte_t* data); void ReaderIso14443a(UsbCommand * c); @@ -114,16 +114,11 @@ void ReaderIso14443a(UsbCommand * c); void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity); void iso14a_set_trigger(bool enable); -void RAMFUNC SniffMifare(uint8_t param); - -/// epa.h +// epa.h void EPA_PACE_Collect_Nonce(UsbCommand * c); void EPA_PACE_Replay(UsbCommand *c); // mifarecmd.h -//void ReaderMifare(bool first_try); -void ReaderMifare(bool first_try, uint8_t block ); -int32_t dist_nt(uint32_t nt1, uint32_t nt2); void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data); void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUC_Auth(uint8_t arg0, uint8_t *datain); @@ -148,33 +143,37 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain); void OnSuccessMagic(); void OnErrorMagic(uint8_t reason); +int32_t dist_nt(uint32_t nt1, uint32_t nt2); +void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ); +void RAMFUNC SniffMifare(uint8_t param); + //desfire void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain); void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); // mifaredesfire.h -bool InitDesfireCard(); -void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain); -void MifareDesfireGetInformation(); -void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain); -void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain); -int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); -size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout); -void OnSuccess(); -void OnError(uint8_t reason); +bool InitDesfireCard(); +void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain); +void MifareDesfireGetInformation(); +void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain); +void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain); +int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); +size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout); +void OnSuccess(); +void OnError(uint8_t reason); // desfire_crypto.h -void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings); -void *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbytes, int communication_settings); -void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); -void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); -size_t key_block_size (const desfirekey_t key); -size_t padded_data_length (const size_t nbytes, const size_t block_size); -size_t maced_data_length (const desfirekey_t key, const size_t nbytes); -size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings); -void cmac_generate_subkeys (desfirekey_t key); -void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); +void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings); +void *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbytes, int communication_settings); +void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); +void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); +size_t key_block_size (const desfirekey_t key); +size_t padded_data_length (const size_t nbytes, const size_t block_size); +size_t maced_data_length (const desfirekey_t key, const size_t nbytes); +size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings); +void cmac_generate_subkeys (desfirekey_t key); +void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); /// iso15693.h void RecordRawAdcSamplesIso15693(void); @@ -199,7 +198,6 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks); void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data); void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType); - // hitag2.h void SnoopHitag(uint32_t type); void SimulateHitagTag(bool tag_mem_supplied, byte_t* data); @@ -211,13 +209,13 @@ void ReadHitagS(hitag_function htf, hitag_data* htd); void WritePageHitagS(hitag_function htf, hitag_data* htd,int page); void check_challenges(bool file_given, byte_t* data); - // cmd.h bool cmd_receive(UsbCommand* cmd); bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len); -/// util.h +// util.h void HfSnoop(int , int); + //EMV functions emvcmd.h void EMVTransaction(void); void EMVgetUDOL(void); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f9dfebd9..a2014079 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2175,8 +2175,9 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { // Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime" // (article by Nicolas T. Courtois, 2009) //----------------------------------------------------------------------------- -void ReaderMifare(bool first_try, uint8_t block ) { - uint8_t mf_auth[] = { MIFARE_AUTH_KEYA, block, 0x00, 0x00 }; +void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { + + uint8_t mf_auth[] = { keytype, block, 0x00, 0x00 }; uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; uint8_t par_list[8] = {0,0,0,0,0,0,0,0}; @@ -2209,13 +2210,14 @@ void ReaderMifare(bool first_try, uint8_t block ) { #define PRNG_SEQUENCE_LENGTH (1 << 16) #define MAX_UNEXPECTED_RANDOM 4 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up. #define MAX_SYNC_TRIES 32 - + + AppendCrc14443a(mf_auth, 2); + BigBuf_free(); BigBuf_Clear_ext(false); clear_trace(); set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - AppendCrc14443a(mf_auth, 2); if (first_try) { sync_time = GetCountSspClk() & 0xfffffff8; diff --git a/armsrc/util.h b/armsrc/util.h index 486f22e9..05364519 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -37,6 +37,9 @@ #ifndef BITMASK # define BITMASK(X) (1 << (X)) #endif +#ifndef ARRAYLEN +# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) +#endif void print_result(char *name, uint8_t *buf, size_t len); size_t nbytes(size_t nbits); diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index f2efd3a6..0ab2463d 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -176,7 +176,16 @@ int CmdAnalyseCRC(const char *Cmd) { PrintAndLog("LEGIC: CRC8 : %X (0xC6 expected)", legic8); PrintAndLog("MAXIM: CRC8 : %X (0xA1 expected)", CRC8Maxim(dataStr, sizeof(dataStr))); PrintAndLog("DNP : CRC16: %X (0x82EA expected)", CRC16_DNP(dataStr, sizeof(dataStr))); - PrintAndLog("CCITT: CRC16: %X (0xE5CC expected)", CRC16_CCITT(dataStr, sizeof(dataStr))); + PrintAndLog("CCITT: CRC16: %X (0xE5CC expected)", CRC16_CCITT(dataStr, sizeof(dataStr))); + + PrintAndLog("ICLASS org: CRC16: %X (0x expected)",iclass_crc16( (char*)dataStr, sizeof(dataStr))); + PrintAndLog("ICLASS ice: CRC16: %X (0x expected)",CRC16_ICLASS(dataStr, sizeof(dataStr))); + + + + uint8_t dataStr1234[] = { 0x1,0x2,0x3,0x4}; + PrintAndLog("ISO15693 org: : CRC16: %X (0xF0B8 expected)", Iso15693Crc(dataStr1234, sizeof(dataStr1234))); + PrintAndLog("ISO15693 ice: : CRC16: %X (0xF0B8 expected)", CRC16_Iso15693(dataStr1234, sizeof(dataStr1234))); free(data); return 0; diff --git a/client/cmdanalyse.h b/client/cmdanalyse.h index 40ca961b..ddce0ecc 100644 --- a/client/cmdanalyse.h +++ b/client/cmdanalyse.h @@ -18,6 +18,7 @@ #include "ui.h" // PrintAndLog #include "util.h" #include "crc.h" +#include "../common/iso15693tools.h" int usage_analyse_lcr(void); int usage_analyse_checksum(void); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 9b43f411..1988fa16 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -9,18 +9,18 @@ //----------------------------------------------------------------------------- #include "cmdhfmf.h" -#include "cmdhfmfhard.h" -#include "nonce2key/nonce2key.h" static int CmdHelp(const char *Cmd); int usage_hf14_mifare(void){ - PrintAndLog("Usage: hf mf mifare [h] "); + PrintAndLog("Usage: hf mf mifare [h] "); PrintAndLog("options:"); - PrintAndLog(" h this help"); - PrintAndLog(" (Optional) target other key A than block 0."); + PrintAndLog(" h this help"); + PrintAndLog(" (Optional) target other block"); + PrintAndLog(" (optional) target key type"); PrintAndLog("samples:"); PrintAndLog(" hf mf mifare"); PrintAndLog(" hf mf mifare 16"); + PrintAndLog(" hf mf mifare 16 B"); return 0; } int usage_hf14_mf1ksim(void){ @@ -132,13 +132,18 @@ int CmdHF14AMifare(const char *Cmd) { uint64_t par_list = 0, ks_list = 0, r_key = 0; int16_t isOK = 0; int tmpchar; - uint8_t blockNo = 0; + uint8_t blockNo = 0, keytype = MIFARE_AUTH_KEYA; char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_mifare(); - blockNo = param_get8(Cmd, 0); - UsbCommand c = {CMD_READER_MIFARE, {true, blockNo, 0}}; + blockNo = param_get8(Cmd, 0); + + cmdp = param_getchar(Cmd, 1); + if (cmdp == 'B' || cmdp == 'b') + keytype = MIFARE_AUTH_KEYB; + + UsbCommand c = {CMD_READER_MIFARE, {true, blockNo, keytype}}; // message printf("-------------------------------------------------------------------------\n"); @@ -1315,45 +1320,121 @@ int CmdHF14AMfChk(const char *Cmd) { PrintAndLog(""); return 0; } +#define ATTACK_KEY_COUNT 8 +sector *k_sector = NULL; +uint8_t k_sectorsCount = 16; +void readerAttack(nonces_t data[], bool setEmulatorMem) { -int CmdHF14AMf1kSim(const char *Cmd) { - uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t exitAfterNReads = 0; - uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA); - int uidlen = 0; - uint8_t pnr = 0; - uint8_t cmdp = param_getchar(Cmd, 0); - - if (cmdp == 'h' || cmdp == 'H') return usage_hf14_mf1ksim(); - - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'u' || cmdp == 'U') { - param_gethex_ex(Cmd, pnr+1, uid, &uidlen); - switch(uidlen){ - case 20: flags = FLAG_10B_UID_IN_DATA; break; - case 14: flags = FLAG_7B_UID_IN_DATA; break; - case 8: flags = FLAG_4B_UID_IN_DATA; break; - default: return usage_hf14_mf1ksim(); - } - pnr +=2; - } + // initialize storage for found keys + if (k_sector == NULL); + k_sector = calloc(k_sectorsCount, sizeof(sector)); + if (k_sector == NULL) + return; - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'n' || cmdp == 'N') { - exitAfterNReads = param_get8(Cmd, pnr+1); - pnr += 2; + uint64_t key = 0; + + // empty e_sector + for(int i = 0; i < k_sectorsCount; ++i){ + k_sector[i].Key[0] = 0xffffffffffff; + k_sector[i].Key[1] = 0xffffffffffff; + k_sector[i].foundKey[0] = FALSE; + k_sector[i].foundKey[1] = FALSE; } - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'i' || cmdp == 'I' ) { - flags |= FLAG_INTERACTIVE; - pnr++; + printf("enter reader attack\n"); + for (uint8_t i = 0; i < ATTACK_KEY_COUNT; ++i) { + if (data[i].ar2 > 0) { + + if (tryMfk32(data[i], &key)) { + PrintAndLog("Found Key%s for sector %02d: [%012"llx"]" + , (data[i].keytype) ? "B" : "A" + , data[i].sector + , key + ); + + k_sector[i].Key[data[i].keytype] = key; + k_sector[i].foundKey[data[i].keytype] = TRUE; + + //set emulator memory for keys + if (setEmulatorMem) { + uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0}; + num_to_bytes( k_sector[i].Key[0], 6, memBlock); + num_to_bytes( k_sector[i].Key[1], 6, memBlock+10); + mfEmlSetMem( memBlock, i*4 + 3, 1); + PrintAndLog("Setting Emulator Memory Block %02d: [%s]" + , i*4 + 3 + , sprint_hex( memBlock, sizeof(memBlock)) + ); + } + break; + } + //moebius attack + // if (tryMfk32_moebius(data[i+ATTACK_KEY_COUNT], &key)) { + // PrintAndLog("M-Found Key%s for sector %02d: [%012"llx"]" + // ,(data[i+ATTACK_KEY_COUNT].keytype) ? "B" : "A" + // , data[i+ATTACK_KEY_COUNT].sector + // , key + // ); + // } + } } +} + +int CmdHF14AMf1kSim(const char *Cmd) { - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'x' || cmdp == 'X') { - flags |= FLAG_NR_AR_ATTACK; + uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t exitAfterNReads = 0; + uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA); + int uidlen = 0; + bool setEmulatorMem = false; + uint8_t cmdp = 0; + bool errors = false; + + while(param_getchar(Cmd, cmdp) != 0x00) { + switch(param_getchar(Cmd, cmdp)) { + case 'e': + case 'E': + setEmulatorMem = true; + cmdp++; + break; + case 'h': + case 'H': + return usage_hf14_mf1ksim(); + case 'i': + case 'I': + flags |= FLAG_INTERACTIVE; + cmdp++; + break; + case 'n': + case 'N': + exitAfterNReads = param_get8(Cmd, cmdp+1); + cmdp += 2; + break; + case 'u': + case 'U': + param_gethex_ex(Cmd, cmdp+1, uid, &uidlen); + switch(uidlen) { + case 20: flags = FLAG_10B_UID_IN_DATA; break; + case 14: flags = FLAG_7B_UID_IN_DATA; break; + case 8: flags = FLAG_4B_UID_IN_DATA; break; + default: return usage_hf14_mf1ksim(); + } + cmdp +=2; + break; + case 'x': + case 'X': + flags |= FLAG_NR_AR_ATTACK; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; } + //Validations + if(errors) return usage_hf14_mf1ksim(); PrintAndLog(" uid:%s, numreads:%d, flags:%d (0x%02x) " , (uidlen == 0 ) ? "N/A" : sprint_hex(uid, uidlen>>1) @@ -1367,24 +1448,24 @@ int CmdHF14AMf1kSim(const char *Cmd) { SendCommand(&c); if(flags & FLAG_INTERACTIVE) { - uint8_t data[32]; - uint64_t key; - UsbCommand resp; PrintAndLog("Press pm3-button or send another cmd to abort simulation"); + + nonces_t data[ATTACK_KEY_COUNT*2]; + UsbCommand resp; + while( !ukbhit() ){ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue; if ( !(flags & FLAG_NR_AR_ATTACK) ) break; if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break; - memset(data, 0x00, sizeof(data)); - int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; - - memcpy(data, resp.d.asBytes, len); - key = 0; - bool found = tryMfk32(data, &key); - found ^= tryMfk32_moebius(data, &key); - if ( found ) break; + memcpy( data, resp.d.asBytes, sizeof(data) ); + readerAttack(data, setEmulatorMem); + } + + if (k_sector != NULL) { + printKeyTable(k_sectorsCount, k_sector ); + free(k_sector); } } return 0; @@ -1548,7 +1629,7 @@ int CmdHF14AMfSniff(const char *Cmd){ int CmdHF14AMfDbg(const char *Cmd) { char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h'|| ctmp == 'H') return usage_hf14_dbg(); + if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_dbg(); uint8_t dbgMode = param_get8ex(Cmd, 0, 0, 10); if (dbgMode > 4) return usage_hf14_dbg(); @@ -1572,7 +1653,6 @@ void printKeyTable( uint8_t sectorscnt, sector *e_sector ){ } // EMULATOR COMMANDS - int CmdHF14AMfEGet(const char *Cmd) { uint8_t blockNo = 0; @@ -1586,7 +1666,7 @@ int CmdHF14AMfEGet(const char *Cmd) blockNo = param_get8(Cmd, 0); - PrintAndLog(" "); + PrintAndLog(""); if (!mfEmlGetMem(data, blockNo, 1)) { PrintAndLog("data[%3d]:%s", blockNo, sprint_hex(data, 16)); } else { diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 029e12d5..d542b367 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -22,7 +22,10 @@ #include "cmdparser.h" #include "common.h" #include "util.h" -#include "mifarehost.h" +//#include "mifarehost.h" +#include "mifare.h" // nonces_t struct +#include "cmdhfmfhard.h" +#include "nonce2key/nonce2key.h" int CmdHFMF(const char *Cmd); @@ -56,5 +59,6 @@ int CmdHF14AMfCLoad(const char* cmd); int CmdHF14AMfCSave(const char* cmd); int CmdHf14MfDecryptBytes(const char *Cmd); +void readerAttack(nonces_t data[], bool setEmulatorMem); void printKeyTable( uint8_t sectorscnt, sector *e_sector ); #endif diff --git a/client/util.h b/client/util.h index 3acceafd..f81d7d88 100644 --- a/client/util.h +++ b/client/util.h @@ -24,12 +24,15 @@ #ifndef ROTR # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) #endif + #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX # define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif + +// Byte swapping #ifndef BSWAP_32 # define BSWAP_32(x) \ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ @@ -39,11 +42,13 @@ # define BSWAP_16(x) ((( ((x) & 0xFF00 ) >> 8))| ( (((x) & 0x00FF) << 8))) #endif +// Boolean #define TRUE 1 #define FALSE 0 #define EVEN 0 #define ODD 1 +// Nibble logic #ifndef NIBBLE_HIGH # define NIBBLE_HIGH(b) ( (b & 0xF0) >> 4 ) #endif @@ -57,6 +62,7 @@ # define SWAP_NIBBLE(b) ( (NIBBLE_LOW(b)<< 4) | NIBBLE_HIGH(b)) #endif +// Binary Encoded Digit #ifndef BCD2DEC # define BCD2DEC(bcd) HornerScheme(bcd, 0x10, 10) #endif @@ -64,6 +70,15 @@ # define DEC2BCD(dec) HornerScheme(dec, 10, 0x10) #endif +// used for save/load files +#ifndef FILE_PATH_SIZE +# define FILE_PATH_SIZE 1000 +#endif + +#ifndef ARRAYLEN +# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) +#endif + int ukbhit(void); void AddLogLine(char *fileName, char *extData, char *c); -- 2.39.2