コード例 #1
0
ファイル: awid.c プロジェクト: 10to7/RFIDler
// convert 96 bit AWID FSK data to 8 digit BCD UID
BOOL awid26_hex_to_uid(unsigned char *response, unsigned char *awid26)
{
    BYTE i, tmp[96], tmp1[7];
    unsigned int site;
    unsigned int id;

    if(!hextobinarray(tmp, awid26))
        return FALSE;

    // data is in blocks of 4 bits - every 4th bit is parity, except the first
    // block which is all zeros
    for(i= 0 ; i < 4 ; ++i)
        if(tmp[i] != 0x00)
            return FALSE;

    // discard 1st block
    memcpy(tmp, tmp + 4, 92);

    // check and strip parity on the rest
    for(i= 1 ; i < 23 ; ++i)
        if(tmp[(i * 4) - 1] != parity(tmp + (i - 1) * 4, ODD, 3))
            return FALSE;
        else
            memcpy((tmp + (i - 1) * 3), tmp + (i - 1) * 4, 3);

    // discard the rest of the header - 1 more 3 bit block
    memcpy(tmp, tmp + 3, 66);

    // next 8 bits is data length - should be 26: 0x1A
    binarraytohex(tmp1, tmp, 8);
    if(strcmp(tmp1, "1A") != 0)
        return FALSE;
    memcpy(tmp, tmp +8, 58);

    // standard wiegand parity check - even for 1st 12 bits, odd for 2nd 12
    if(tmp[0] != parity(tmp + 1, EVEN, 12))
        return FALSE;
    if(tmp[25] != parity(tmp + 13, ODD, 12))
        return FALSE;

    // convert to hex, ignoring parity bits
    if(!binarraytohex(tmp1, tmp + 1, 24))
        return FALSE;

    // convert hex to site/id
    sscanf(tmp1,"%2X%4X", &site, &id);

    // final output 8 byte BCD
    sprintf(response,"%03d%05d", site, id);

    return TRUE;
}
コード例 #2
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
BOOL hitag1_get_uid(BYTE *response)
{
    BYTE tmp[132]; // 33 bits x 4

    rwd_send(HITAG1_SET_CC, strlen(HITAG1_SET_CC), RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Sleep_Period, RFIDlerConfig.RWD_Wake_Period, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX);
    // get tag id in anti-collision mode (proprietary data format, so switch off manchester and read at double the data rate, for 4 x the data bits)
    RFIDlerConfig.Manchester= FALSE;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate / 2, tmp, RFIDlerConfig.DataBits * 4, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == RFIDlerConfig.DataBits * 4)
    {
        if (hitag_ac_to_bin(tmp, tmp, 132))
        {
            // check sync bit
            if(tmp[0] != 0x01)
                return FALSE;
            binarraytohex(response, tmp + 1, 32);
            RFIDlerConfig.Manchester= TRUE;
            // delay for RX->TX period
            Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wait_Switch_RX_TX) / 100);
            return TRUE;
        }
    }
    RFIDlerConfig.Manchester= TRUE;

    return FALSE;
}
コード例 #3
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
// auth in password mode
BOOL hitag2_pwd_auth(BYTE *response, BYTE *pwd)
{
    BYTE tmp[37];

    // restart the tag
    if(!hitag2_get_uid(tmp))
        return FALSE;

    if(strlen(pwd) == 0)
        pwd= HITAG2_PWD_DEFAULT;

    // use default transport key if none specified
    if(!hextobinstring(tmp, pwd))
        return FALSE;

    // wait for RX->TX period, then send 32 bit PWD
    if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // skip 1/2 bit to synchronise manchester
    HW_Skip_Bits= 1;
    // get 37 bit response: sync + config byte + 24 bit TAG pwd
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 37)
    {
        // check sync bits
        if (memcmp(tmp, Hitag2Sync, 5) != 0)
            return FALSE;
        binarraytohex(response, tmp + 5, 32);
        return TRUE;
    }
    return FALSE;
}
コード例 #4
0
ファイル: hdx.c プロジェクト: ApertureLabsLtd/RFIDler
// HDX reads data in Half Duplex mode
// first we energise the TAG for long enough that it charges up
// then we use sniffer to read response
// each bit is 16 ticks, a 1 is 124.2 KHz and a 0 is 134.2 KHz
// activation frequency is 134.2 KHz (745 FCs))
BOOL hdx_get_uid(BYTE *response)
{
    BYTE i;
    BYTE tmp[HDX_DATABITS];
    
    // this is a work in progress, so until reading produces any data, return empty
    return FALSE;

    // energise tag & wait for wakeup period
    InitHWReaderClock(OC_TOGGLE_PULSE, 745 / 2L, 745, RWD_STATE_ACTIVE);
    Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wake_Period) / 100);

    // switch off clock and switch to sniffer mode
    detect_init();

    // read to temporary array for speed
    for(i= 0 ; i < HDX_DATABITS ; ++i)
        tmp[i]= read_external_clock_burst(16) / 1000L;

    // convert to binary based on freq +- 3
    for(i= 0 ; i < HDX_DATABITS ; ++i)
    {
        if (tmp[i] >= 122 && tmp[i] <= 128)
            tmp[i]= 0x01;
        else
            if (tmp[i] >= 129 && tmp[i] <= 135)
                 tmp[i]= 0x00;
            else
                return FALSE;
    }
    binarraytohex(response, tmp, HDX_DATABITS);
    return TRUE;
}
コード例 #5
0
ファイル: hid.c プロジェクト: ApertureLabsLtd/RFIDler
// convert null-terminated BCD UID (8 digits) to hid26 encoded hex
// UID is SSSIIIII where S is site-code and I is ID
BOOL bcd_to_hid26_hex(unsigned char *hid26, unsigned char *bcd)
{
    if(bcd_to_hid26_bin(hid26, bcd))
        return binarraytohex(hid26, hid26, 96);
    else
        return FALSE;
}
コード例 #6
0
ファイル: unique.c プロジェクト: 10to7/RFIDler
// convert null-terminated hex UID (10 hex digits) to 64 bit unique encoded hex
BOOL hex_to_unique_hex(unsigned char *unique, unsigned char *hex)
{
    if(hex_to_unique_bin(unique, hex))
        return binarraytohex(unique, unique, 64);
    else
        return FALSE;
}
コード例 #7
0
ファイル: em.c プロジェクト: androdev4u/RFIDler
// convert null-terminated hex UID (10 digits) to em4x02 encoded hex
BOOL hex_to_em4x02_hex(unsigned char *em, unsigned char *hex)
{
    if(hex_to_em4x02_bin(em, hex))
        return binarraytohex(em, em, 64);
    else
        return FALSE;
}
コード例 #8
0
ファイル: awid.c プロジェクト: 10to7/RFIDler
// convert null-terminated BCD UID (8 digits) to awid26 encoded hex
// UID is SSSIIIII where S is site-code and I is ID
BOOL bcd_to_awid26_hex(unsigned char *awid26, unsigned char *bcd)
{
    if(bcd_to_awid26_bin(awid26, bcd))
        return binarraytohex(awid26, awid26, 96);
    else
        return FALSE;
}
コード例 #9
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
// read page - 32 bits
// pages 2 - 15 are probably not readable!
BOOL hitag1_read_page(BYTE *response, BYTE block)
{
    BYTE tmp[HITAG1_BLOCKSIZE + 6]; // 32 bits plus 6 sync bits

    if(block > HITAG1_DATABLOCKS - 1)
        return FALSE;

    // get tag's UID for select command
    if(!hitag1_get_uid(tmp))
        return FALSE;

    // select for read/write
    hitag1_select(tmp, tmp);

    // create 12 bit command block: HITAG1_RDPPAGE + 8 bits address
    strcpy(tmp, HITAG1_RDPPAGE);
    inttobinstring(tmp + 4, (unsigned int) block, 8);
    tmp[12]= '\0';

    // ??? docs say 6 sync bits!
    if(!hitag1_send_command(tmp, tmp, NO_RESET, NO_SYNC, HITAG1_BLOCKSIZE + 1, NO_ACK))
        return FALSE;

    // check sync
    if(tmp[0] != 0x01)
        return FALSE;

    binarraytohex(response, tmp + 1, HITAG1_BLOCKSIZE);

    return TRUE;
}
コード例 #10
0
ファイル: hid.c プロジェクト: ApertureLabsLtd/RFIDler
// convert 96 bit HID FSK data to 8 digit BCD UID
BOOL hid26_hex_to_uid(unsigned char *response, unsigned char *hid26)
{
    BYTE tmp[96], tmp1[7];
    unsigned int site;
    unsigned int id;
    // todo parity checking etc.

    if(!hextobinarray(tmp, hid26))
        return FALSE;
    
    // skip 44 bit header
    memcpy(tmp, tmp + 44, 52);
    
    // manchester decode
    if(manchester_decode(tmp, tmp, 52) != 26)
        return FALSE;

    // convert to hex, ignoring parity bits
    if(!binarraytohex(tmp1, tmp + 1, 24))
        return FALSE;
    // convert hex to site/id
    sscanf(tmp1,"%2X%4X", &site, &id);
    // final output 8 byte BCD
    sprintf(response,"%03d%05d", site, id);

    return TRUE;
}
コード例 #11
0
ファイル: em.c プロジェクト: androdev4u/RFIDler
BOOL em4x02_hex_to_uid(BYTE *response, BYTE *hex)
{
    BYTE tmp[40];

    if(em4x02_hex_to_bin(tmp, hex))
        return binarraytohex(response, tmp, 40);
    return FALSE;
}
コード例 #12
0
ファイル: hdx.c プロジェクト: ApertureLabsLtd/RFIDler
// convert human readable UID to 128 bit fdx-b HEX string
BOOL uid_to_hdx_hex(BYTE *hex, BYTE *uid)
{
    BYTE tmp[128];
    if(!uid_to_fdxb_bin(tmp, uid))
        return FALSE;

   binarraytohex(hex, tmp, 128);
   return TRUE;
}
コード例 #13
0
ファイル: unique.c プロジェクト: 10to7/RFIDler
// convert 64 bit unique encoded hex to 10 hex digit 40 bit UID
// this is the same as em4x02 but with final output bits in a different order
BOOL unique_hex_to_hex(unsigned char *hex, unsigned char *unique)
{
    BYTE tmp[64];

    if(em4x02_hex_to_bin(tmp, unique))
    {
        string_reverse(tmp, 40);
        binarraytohex(hex, tmp, 40);
        string_byteswap(hex,10);
        string_reverse(hex, 10);
        return TRUE;
    }
    return FALSE;
}
コード例 #14
0
ファイル: hitag.c プロジェクト: hhcalder92/RFIDler
BOOL hitag2_get_uid(BYTE *response)
{
    BYTE tmp[37];

    // START_AUTH kills active crypto session
    CryptoActive= FALSE;

    if(!rwd_send(HITAG2_START_AUTH, strlen(HITAG2_START_AUTH), RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Sleep_Period, RFIDlerConfig.RWD_Wake_Period, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == RFIDlerConfig.DataBits)
    {
        // check sync bits
        if (memcmp(tmp, Hitag2Sync, 5) != 0)
            return FALSE;
        binarraytohex(response, tmp + 5, 32);
        return TRUE;
    }
    return FALSE;
}
コード例 #15
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
// select HITAG1 for read/write operations - return config page
BOOL hitag1_select(BYTE *response, BYTE *uid)
{
    BYTE command[38], tmp1[33]; // command: 5 bit command + 32 bit uid + NULL

    strcpy(command, HITAG1_SELECT);
    if(!hextobinstring(command + 5, uid))
        return FALSE;

    // send command and get back 1 sync bit + 32 bit configpage
    if(!hitag1_send_command(tmp1, command, NO_RESET, NO_SYNC, 33, NO_ACK))
        return FALSE;

    // check sync bit
    if(tmp1[0] == 0x01)
    {
        binarraytohex(response, tmp1 + 1, 32);
        return TRUE;
    }
    return FALSE;
}
コード例 #16
0
ファイル: tags.c プロジェクト: nsdown/RFIDler
// copy raw UID to data blocks for re-transmission by target tag
void tag_raw_uid_to_data(BYTE *data, BYTE *uid, BYTE host_tagtype)
{
    BYTE            tmp[MAXUID + 1];
    unsigned int    i;
    
    switch(host_tagtype)
    {
        // EM4X05 sends everything LSB, so reverse data
        case TAG_TYPE_EM4X05:
            hextobinarray(tmp, uid);
            for(i= 0 ; i < HEXTOBITS(strlen(uid)) ; i += EM4X05_BLOCKSIZE)
                string_reverse(tmp + i, EM4X05_BLOCKSIZE);
            binarraytohex(data, tmp, HEXTOBITS(strlen(uid)));
            break;
            
        // for most tags a straight copy will do
        default:
            strcpy(data, uid);
            break;
    }
}
コード例 #17
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
BOOL hitag2_read_page(BYTE *response, BYTE block)
{
    BYTE tmp[37];

    if(block > HITAG2_DATABLOCKS - 1)
        return FALSE;

    // create 10 bit command block: HITAG2_READ_PAGE + 3 bits address + invert(HITAG2_READ_PAGE + 3 bits address)
    memcpy(tmp, HITAG2_READ_PAGE, 2);
    inttobinstring(tmp + 2, (unsigned int) block, 3);
    invertbinstring(tmp + 5, tmp);
    tmp[10]= '\0';

    // encrypt command if in crypto mode
    if(CryptoActive)
        hitag2_binstring_crypt(tmp, tmp);

    // send with RX->TX delay and no reset
    if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // skip 1/2 bit to synchronise manchester
    HW_Skip_Bits= 1;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 37)
    {
        // check sync bits
        if (memcmp(tmp, Hitag2Sync, 5) != 0)
            return FALSE;
        binarraytohex(response, tmp + 5, 32);

        // decrypt
        if(CryptoActive)
            return hitag2_hex_crypt(response, response);

        return TRUE;
    }
    return FALSE;
}
コード例 #18
0
ファイル: ask.c プロジェクト: 10to7/RFIDler
// specify oneshot if data is not repeated (i.e. in response to a command rather than a cycling UID)
unsigned int read_ask_data(unsigned int period_us, unsigned int ticks, BYTE *data, unsigned int bits, unsigned char *sync, unsigned char syncbits, unsigned int timeout_us, BOOL oneshot, BYTE format)
{
    unsigned int i, j;
    BOOL found= FALSE;
    BYTE repeat= 0;

    // if we're not doing a 1-shot read, we can grab double the data to allow for sync search
    if(oneshot)
        repeat= 1;
    else
        repeat= 2;

    if(!read_ASK_HW_clock(period_us, ticks, TmpBits, bits * repeat, timeout_us, oneshot))
        return 0;

    if(FakeRead)
        return 0;

    // reset timer
    if(timeout_us)
        GetTimer_us(RESET);

    // wait for semaphore to tell us read has finished
    while(mLED_Read == mLED_ON)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return 0;

    if(Manchester_Error)
        return 0;

    // find start of data
    if(syncbits)
    {
        for(i= j= found= 0 ; i < bits * repeat ; ++i)
        {        
            if(TmpBits[i] == getbit(sync[j / 8], 7 - (j % 8)))
                ++j;
            else
            {
                i -= j;
                j= 0;
            }

            if(j == syncbits)
            {
                found= TRUE;
                break;
            }
        }
        if(!found)
            return 0;
    }

    // point at start of sync
    if(syncbits)
        i -= syncbits - 1;
    else
        i= 0;

    // copy to output buffer
    switch(format)
    {
        case HEX:
            return binarraytohex(data, TmpBits + i, bits);
            
        case BINARY:
        default:
            memcpy(data, TmpBits + i, bits);
            return bits;
    }
}
コード例 #19
0
ファイル: hitag.c プロジェクト: chinnyannieb/RFIDler
// note that PRN is not created with security in mind - just using a simple seed
BOOL hitag2_crypto_auth(BYTE *response, BYTE *hexkey)
{
    BYTE tmp[65], tmphex[9];
    unsigned long long key;
    unsigned long uid;
    unsigned long initvec;

    // use default transport key if none specified
    if(strlen(hexkey) == 0)
        hexkey= HITAG2_KEY_DEFAULT;

    // get UID for initialisation
    if(!hitag2_get_uid(tmp))
        return FALSE;

    // convert to numerics for crypto routines
    uid= hexreversetoulong(tmp);
    key= hexreversetoulonglong(hexkey);

    // generate 32 bit PRN for challenge
    srand(Led_Count);
    initvec= rand();
    initvec <<= 16;
    initvec += rand();

    // prepare to send IV in the clear to tag
    ulongtobinstring(tmp, initvec, 32);

    // convert IV to MSB for crypto routines
    binstringtohex(tmphex, tmp);
    initvec= hexreversetoulong(tmphex);

    // initialise  crypto
    hitag2_init(&Hitag_Crypto_State, rev64(key), rev32(uid), rev32(initvec));

    // send inverse of 1st 32bits of keystream to tag for authentication
    ulongtobinstring(tmp + 32, hitag2_crypt(0xFFFFFFFF, 32), 32);

    // restart the tag & auth process
    if(!hitag2_get_uid(TmpBuff))
        return FALSE;

    // wait for RX->TX period, then send PRN+secret
    if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // skip 1/2 bit to synchronise manchester
    HW_Skip_Bits= 1;
    // get 37 bit response: sync + config byte + 24 bit TAG pwd
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 37)
    {
        // check sync bits
        if (memcmp(tmp, Hitag2Sync, 5) != 0)
            return FALSE;
        CryptoActive= TRUE;

        // decrypt
        binarraytohex(response, tmp + 5, 32);
        return hitag2_hex_crypt(response, response);
    }
    return FALSE;
}
コード例 #20
0
ファイル: psk.c プロジェクト: zhihuawang/RFIDler
// read a PSK1 bitstream and find start of data
//
// parameters:
//
//   period_us    - clock period in uS
//   ticks        - clock periods per bit
//   data         - buffer for final data [no. of bits])
//   bits         - no. of bits to read (always specify in bits, not bytes)
//   leadin       - no. of leading '0' bits
//   bytes        - if set, return data as bytes, otherwise bits
//   timeout_us   - timeout in uS, 0 for blocking
//   min_pulse_us - mininum pulse width from external reader for 'good' read. 0 for read anything.
//
// return:
//
//   data will be filled with one byte per bit (value 0x00 or 0x01)
//   return will be 0 if leadin not found, or no. of BITS read
// specify oneshot if data is not repeated (i.e. in response to a command rather than a cycling UID)
unsigned int read_psk1_data(unsigned int period_us, unsigned int ticks, BYTE *data, unsigned int bits, unsigned char *sync, unsigned char syncbits, unsigned int timeout_us, unsigned int min_pulse_us, BOOL oneshot, BYTE format)
{
    unsigned int i= 0, j;
    BYTE found= 0, inverted= 0, repeat;

    if(oneshot)
        repeat= 1;
    else
        repeat= 2;

    // if we're not doing a 1-shot read, we can grab double the data to allow for sync search
    read_PSK1_HW_clock(period_us, ticks, TmpBits, bits * repeat, timeout_us, min_pulse_us);

    if(FakeRead)
        return 0;

    // reset timer
    if(timeout_us)
        GetTimer_us(RESET);

    // wait for semaphore to tell us read has finished
    while(mLED_Read == mLED_ON)
        if(timeout_us)
            if (GetTimer_us(NO_RESET) > timeout_us)
                return 0;

    if(PSK_Read_Error)
        return 0;

    // find start of data
    while(syncbits)
    {
        for(i= j= found= 0 ; i < bits * repeat ; ++i)
        {
            if(TmpBits[i] == getbit(sync[j / 8], 7 - (j % 8)))
                ++j;
            else
            {
                i -= j;
                j= 0;
            }

            if(j == syncbits)
            {
                found= 1;
                break;
            }
        }

        // point at start of sync
        i -= syncbits - 1;

        if(found)
            break;
        if(inverted)
            return 0;
        // with PSK we have no way of knowing if 1st bit was a 0 or 1, so invert data and try again
        inverted= 1;
        for(i= 0 ; i < bits * repeat ; ++i)
            TmpBits[i] ^= 1;
    }

    // copy to output buffer
    switch(format)
    {
    case HEX:
        return binarraytohex(data, TmpBits + i, bits);

    case BINARY:
    default:
        memcpy(data, TmpBits + i, bits);
        data[bits]= '\0';
        return bits;
    }
}