Example #1
0
// q5 needs special timings etc., so have a master send command routine to keep things simple
// response length in bits
BOOL q5_send_command(BYTE *response, BYTE *command, BYTE length, BOOL reset, BOOL sync, BYTE response_length)
{
    // send command
    if(!rwd_send(command, length, reset, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, Q5_START_GAP - RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    if(!response_length)
        return TRUE;

    // wait for Q5 damping to kick in: q5 may create a false pulse during RWD receipt, so wait for it to recognise
    // command and shut down before trying to read response.
    GetTimer_us(RESET);
    while(READER_DATA)
        if(GetTimer_us(NO_RESET) > RFIDlerConfig.Timeout)
            return FALSE;

    // read response as raw data with manchester auto-correct as first bit may be a '0'
    Manchester_Auto_Correct= TRUE;
//    DEBUG_PIN_4= !DEBUG_PIN_4;
//    DEBUG_PIN_4= !DEBUG_PIN_4;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, response, response_length, RFIDlerConfig.Sync, sync ? RFIDlerConfig.SyncBits : 0, RFIDlerConfig.Timeout, ONESHOT_READ, HEX) == response_length)
    {
        // delay for RX->TX time
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wait_Switch_RX_TX) / 100);
        return TRUE;
    }

    return FALSE;
}
Example #2
0
// 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;
}
Example #3
0
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;
}
Example #4
0
// calcuate CRC & send command - response in binarray
BOOL hitag1_send_command(BYTE *response, BYTE *command, BOOL reset, BOOL sync, BYTE response_length)
{
    BYTE crc= HITAG1_CRC_PRESET, tmp[HITAG1_MAX_COMMAND_LEN], length; // supplied command is 4 bits + 8 bit address. we add 8 bit CRC
    
    // calculate crc
    length= binstringtobinarray(tmp, command);
    hitag1_binarray_crc(&crc, tmp, length);

    // add 8 bit crc to command
    inttobinarray(tmp + length, (unsigned int) crc, 8);
    length += 8;

    // send command - first gap is GAP, not SLEEP
    if(!rwd_send(tmp, length, reset, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Gap_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(!response_length)
        return TRUE;

    // read response as binary data
    //Manchester_Auto_Correct= TRUE;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, response, response_length, RFIDlerConfig.Sync, sync ? RFIDlerConfig.SyncBits : 0, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == response_length)
    {
        // delay for RX->TX time
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wait_Switch_RX_TX) / 100);
        return TRUE;
    }

    return FALSE;
}
Example #5
0
// response length in bits
BOOL t55x7_send_command(BYTE *response, BYTE *command, BYTE length, BOOL reset, BOOL sync, BYTE response_length)
{
    // send command
    if(!rwd_send(command, length, reset, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, T55X7_START_GAP - RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    if(!response_length)
        return TRUE;

    // wait for T55x7 damping to kick in: t55x7 may create a false pulse during RWD receipt, so wait for it to recognise
    // command and shut down before trying to read response.
    GetTimer_us(RESET);
    while(READER_DATA)
        if(GetTimer_us(NO_RESET) > RFIDlerConfig.Timeout)
            return FALSE;

    // skip 4 bit Sequence Terminator pattern and leading '0'
    HW_Skip_Bits= 10; // 10 primitive 'bits' manchester encoded

//    DEBUG_PIN_4= !DEBUG_PIN_4;
//    DEBUG_PIN_4= !DEBUG_PIN_4;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, response, response_length, RFIDlerConfig.Sync, sync ? RFIDlerConfig.SyncBits : 0, RFIDlerConfig.Timeout, ONESHOT_READ, HEX) == response_length)
    {
        // delay for RX->TX time
        Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wait_Switch_RX_TX) / 100);
        return TRUE;
    }
    return FALSE;
}
Example #6
0
// try to find values that correctly transmit all commands to q5
// to test this properly, q5 should have invalid data in it's data blocks
// so that only a GET_TRACE_DATA command will return a true value
BOOL q5_rwd_test(BYTE *pattern)
{
    BYTE start_gap, gap, one, zero, i, tmp[Q5_BLOCKSIZE + 1];
    BOOL found= FALSE, blank;

    // min/max from datasheets
    for(one= 48 ; one <= 63 ; ++one)
        for(zero= 16; zero <= 31 ; ++zero)
            for(gap=  10 ; gap <= 50 ; ++gap)
                for(start_gap= 11 ; start_gap <= 50 ; ++start_gap)
                {
                    RFIDlerConfig.Manchester= TRUE;
                    blank= TRUE;
                    if(get_user_abort())
                        return found;
                    RFIDlerConfig.RWD_Gap_Period= gap;
                    RFIDlerConfig.RWD_One_Period= one;
                    RFIDlerConfig.RWD_Zero_Period= zero;
                    // reset tag
                    get_tag_uid(tmp);
                    // try to switch off modulation
                    // send command with start gap: reset with sleep time set to start gap, and wake time set to 0 as we transmit the 1st bit immediately
                    // note that we must also subtract standard gap period as it will be added to the front of the first bit by default.
                    rwd_send(Q5_MODULATION_DEFEAT, strlen(Q5_MODULATION_DEFEAT), NO_RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, start_gap - RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX);
                    // read a block with no sync & no manchester - will be all '0' if not modulating
                    RFIDlerConfig.Manchester= FALSE;
                    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, 0, RFIDlerConfig.Timeout, NO_ONESHOT_READ, HEX) == RFIDlerConfig.DataBits)
                    {
                        for(i= 0 ; i < HEXDIGITS(RFIDlerConfig.DataBits) ; ++i)
                            if(tmp[i] != '0')
                                blank= FALSE;
                        RFIDlerConfig.Manchester= TRUE;
                        if(blank && get_tag_uid(tmp) && q5_read_block(tmp, 0))
                        {
                            UserMessageNum("\r\nFound tag with start_gap %d", start_gap);
                            UserMessageNum(" gap %d", gap);
                            UserMessageNum(" one %d", one);
                            UserMessageNum(" zero %d", zero);
                            found= TRUE;
                        }
                    }
                }
    UserMessage("%s", "\r\n");
    return found;
}
Example #7
0
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;
}
Example #8
0
File: ask.c Project: 10to7/RFIDler
// return raw HEX UID
BOOL ask_raw_get_uid(BYTE *response)
{
    unsigned int i;
    BOOL blank= TRUE;
    BYTE tmp[MAXUID + 1];

    memset(tmp, '0', MAXUID);
    tmp[MAXUID]= '\0';

    if (read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, NO_ONESHOT_READ, HEX) != RFIDlerConfig.DataBits)
        return FALSE;

    for(i= 0 ; i < strlen(tmp) ; ++i)
        if(tmp[i] != '0')
            blank= FALSE;
    if(blank)
        return FALSE;

    strcpy(response, tmp);
    return TRUE;
}
Example #9
0
File: q5.c Project: rgooler/RFIDler
// try to find values that correctly transmit all commands to q5
// to test this properly, q5 should have invalid data in it's data blocks
// so that only a GET_TRACE_DATA command will return a true value
BOOL q5_rwd_test(BYTE *pattern)
{
    BYTE gap, one, zero, tmp[Q5_BLOCKSIZE + 1];
    BOOL found= FALSE, blank;

    // min/max from datasheets
    for(one= 48 ; one <= 63 ; ++one)
        for(zero= 16; zero <= 31 ; ++zero)
            for(gap=  10 ; gap <= 50 ; ++gap)
            {
                RFIDlerConfig.Manchester= TRUE;
                blank= TRUE;
                if(get_user_abort())
                    return found;
                RFIDlerConfig.RWD_Gap_Period= gap;
                RFIDlerConfig.RWD_One_Period= one;
                RFIDlerConfig.RWD_Zero_Period= zero;
                // reset tag
                get_tag_uid(tmp);
                // try to switch off modulation
                rwd_send(Q5_MODULATION_DEFEAT, strlen(Q5_MODULATION_DEFEAT), NO_RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX);
                // read a block with no sync & no manchester - will be all '0' if not modulating
                RFIDlerConfig.Manchester= FALSE;
                if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, 0, RFIDlerConfig.Timeout, NO_ONESHOT_READ, HEX) == RFIDlerConfig.DataBits)
                {
                    if(strcmp(tmp, "0000000000000000") != 0)
                            blank= FALSE;
                    RFIDlerConfig.Manchester= TRUE;
                    if(blank && get_tag_uid(tmp) && q5_read_block(tmp, 0))
                    {
                        UserMessageNum("\r\nFound tag with gap %d", gap);
                        UserMessageNum(" one %d", one);
                        UserMessageNum(" zero %d", zero);
                        found= TRUE;
                    }
                }
            }
    UserMessage("%s", "\r\n");
    return found;
}
Example #10
0
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;
}
Example #11
0
BOOL hitag2_write_page(BYTE block, BYTE *data)
{
    BYTE command[11], tmp[37], tmp1[37], tmp2[37], tmphex[9];

    if(block > HITAG2_DATABLOCKS - 1)
        return FALSE;

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

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

    // convert data to binstring for send
    if(hextobinstring(tmp1, data) != 32)
        return FALSE;

    // send command 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;
    // get ACK - 10 bytes + sync
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp2, 15, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 15)
    {
        // check sync bits
        if (memcmp(tmp2, Hitag2Sync, 5) != 0)
            return FALSE;

        // decrypt
        if(CryptoActive)
            hitag2_binarray_crypt(tmp2 + 5, tmp2 + 5, 10);

        // check ACK - should be our original command echo'd back
        binarraytobinstring(tmp2 + 5, tmp2 + 5, 10);
        if(memcmp(command, tmp2 + 5, 10) != 0)
            return FALSE;
    }

    // encrypt data if in crypto mode
    if(CryptoActive)
        hitag2_binstring_crypt(tmp1, tmp1);

    // send data with RX->TX delay and no reset
    if(!rwd_send(tmp1, strlen(tmp1), 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;

    // no ack, so read back and verify
    // delay for long enough to allow write plus RX->TX period
    Delay_us((HITAG2_WRITE_DELAY * RFIDlerConfig.FrameClock + RFIDlerConfig.RWD_Wait_Switch_RX_TX * RFIDlerConfig.FrameClock) / 100);
    if(!hitag2_read_page(tmp, block))
        return FALSE;
    if(memcmp(tmp, data, 8) != 0)
        return FALSE;

    return TRUE;
}
Example #12
0
// 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;
}