Exemplo n.º 1
0
void store_pwm(BYTE *data)
{
    uint32_t count;
    BYTE *entry;
    BYTE datastr[20];
    
    memcpy(&count, (void *)HITAG2_PWM_NVM_ADDRESS, 4);
    
//    UserMessage("current count: %d\r\n", count);
    
    if (count >= HITAG2_PWM_NVM_MAX)
    {
        return;
    }
    
    // convert data from bits to hexstring
    binstringtohex(datastr, data);
    
    // store data
    entry = (BYTE *)HITAG2_PWM_NVM_DATA + (20 * count);
    NVMProgram((void *) entry, (const void *) datastr, 20, (void*) TmpBuff);
    
    // update count
    count++;
    NVMProgram((void *) HITAG2_PWM_NVM_ADDRESS, (const void *) &count, sizeof(uint32_t), (void*) TmpBuff);
//    return;
    

}
Exemplo n.º 2
0
// decode externally sniffed PWM
BOOL hitag2_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count)
{
    unsigned int    i, j;
    BOOL            decoded= FALSE, encrypted= FALSE, auth= FALSE;
    BYTE            out[65], tmp[33], x; // max response from hitag2 is 64 bits

    j= 0;
    while(j < count)
    {
        i= generic_decode_pwm(out, &pulses[j], 10, 256, &gaps[j], 10, 80, count - j);
        if(i)
        {
            // there are only 4 message sizes, so decode accordingly
            switch(strlen(out))
            {
            // start_auth
            case 5:
                auth= FALSE;
                if(memcmp(out, HITAG2_START_AUTH, 5) == 0)
                {
                    UserMessage("\r\n%s, START_AUTH", out);
                    auth= TRUE;
                }
                else
                    UserMessage("\r\n%s, ?INVALID?", out);
                encrypted= FALSE;
                break;

            // read/write/halt
            case 10:
                auth= FALSE;
                if(encrypted)
                {
                    UserMessage("\r\n%s, CMD_ENCRYPTED", out);
                    break;
                }
                if(memcmp(out, HITAG2_HALT, 2) == 0)
                {
                    UserMessage("\r\n%s, HALT", out);
                    break;
                }
                if(memcmp(out, HITAG2_READ_PAGE, 2) == 0)
                    UserMessage("\r\n%s, READ_PAGE:", out);
                if(memcmp(out, HITAG2_READ_PAGE_INVERTED, 2) == 0)
                    UserMessage("\r\n%s, READ_PAGE_INVERTED:", out);
                if(memcmp(out, HITAG2_WRITE_PAGE, 2) == 0)
                    UserMessage("\r\n%s, WRITE_PAGE:", out);
                binstringtobyte(&x, &out[2], 3);
                UserMessageNum("%d", x);
                break;

            // password or data
            case 32:
                if(auth)
                    UserMessage("\r\n%s, PWD:", out);
                else
                    UserMessage("\r\n%s, DATA:", out);
                binstringtohex(out, out);
                UserMessage("%s", out);
                auth= FALSE;
                break;

            // crypto handshake
            case 64:
                UserMessage("\r\n%s, PRN:", out);
                memcpy(tmp, out, 32);
                tmp[32]= '\0';
                binstringtohex(out, tmp);
                UserMessage("%s: SECRET:", out);
                binstringtohex(out, out + 32);
                UserMessage("%s", out);
                encrypted= TRUE;
                auth= FALSE;
                break;

            default:
                UserMessage("\r\n%s,?INVALID?", out);
            }
            decoded= TRUE;
            j += i;
        }
        else
            break;
    }

    UserMessage("%s", "\r\n");

    return decoded;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
// decode externally sniffed PWM
BOOL hitag1_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count)
{
    unsigned int    i, j;
    BOOL            decoded= FALSE;
    BYTE            out[46], tmp[9], x; // max command from hitag1 is 5 bit command plus 32 bits + 8 bit crc == 45

    j= 0;
    while(j < count)
    {
        i= generic_decode_pwm(out, &pulses[j], 10, 256, &gaps[j], 10, 80, count - j);
        if(i)
        {
            // there are only 5 message sizes, so decode accordingly
            switch(strlen(out))
            {
            // halt
            case 4:
                if(memcmp(out, HITAG1_HALT, 4) == 0)
                    UserMessage("\r\n%s, HALT", out);
                else
                    UserMessage("\r\n%s, ?INVALID?", out);
                break;

            // get UID
            case 5:
                if(memcmp(out, HITAG1_SET_CC, 5) == 0)
                    UserMessage("\r\n%s, SET_CC", out);
                else
                    UserMessage("\r\n%s, ?INVALID?", out);
                break;

            // read/write
            case 20:
                if(memcmp(out, HITAG1_RDPPAGE, 4) == 0)
                    UserMessage("\r\n%s, READ_PLAINTEXT_PAGE:", out);
                else if(memcmp(out, HITAG1_WRPPAGE, 4) == 0)
                    UserMessage("\r\n%s, WRITE_PLAINTEXT_PAGE:", out);
                else
                {
                    UserMessage("\r\n%s, ?INVALID?", out);
                    break;
                }
                out[20]= '\0';
                binstringtohex(tmp, out + 4);
                // page
                UserMessage("%.2s:", tmp);
                // crc
                UserMessage("%s", tmp + 2);
                break;

            // data
            case 40:
                UserMessage("\r\n%s, DATA:", out);
                out[40]= '\0';
                binstringtohex(tmp, out);
                // DATA
                UserMessage("%.8s:", tmp);
                // CRC
                UserMessage("%s", tmp + 8);
                break;

            // select
            case 45:
                if(memcmp(out, HITAG1_SELECT, 5) == 0)
                {
                    UserMessage("\r\n%s, SELECT:", out);
                    out[45]= '\0';
                    binstringtohex(tmp, out + 5);
                    // UID
                    UserMessage("%.8s:", tmp);
                    // CRC
                    UserMessage("%s", tmp + 8);
                }
                else
                    UserMessage("\r\n%s, ?INVALID?", out);
                break;

            default:
                UserMessage("\r\n%s,?INVALID?", out);
            }
            decoded= TRUE;
            j += i;
        }
        else
            break;
    }

    UserMessage("%s", "\r\n");

    return decoded;
}
Exemplo n.º 5
0
// decode externally sniffed PWM
BOOL q5_decode_pwm(unsigned int pulses[], unsigned int gaps[], unsigned int count)
{
    unsigned int    i;
    BOOL            decoded= FALSE, sequence;
    static BOOL     pwd= FALSE;
    BYTE            tmp[18], out[71], *p; // max response from q5 is 70 bits
    
    i= 0;
    while(i < count)
    {
        // we can't use generic_decode_pwm as Q5 commands may be all 0 or all 1
        for(p= out, sequence= FALSE ; i < count ; ++i)
            if(gaps[i] >= 100 && gaps[i] <= 512)
            {
                // make sure invalid data doesn't overrun buffer
                if(p - out == sizeof(out) - 2)
                    break;
                
                if(pulses[i] <= 512)
                {
                    if(approx(pulses[i], 128, 20))
                        *(p++)= '0';
                    else
                        *(p++)= '1';
                    sequence= TRUE;
                }
                else
                {
                    ++i;
                    break;
                }
            }
        *p= '\0';
        
        if(sequence)
        {
            // there are only 7 message sizes, so decode accordingly
            switch(strlen(out))
            {
                // GET Trace Data (UID)) or RESET
                case 2:
                    if(memcmp(out, Q5_GET_TRACE_DATA, 2) == 0)
                        UserMessage("\r\n%s, GET_TRACE_DATA", out);
                    else
                        if(memcmp(out, Q5_SOFT_RESET, 2) == 0)
                            UserMessage("\r\n%s, RESET", out);
                        else
                            UserMessage("\r\n%s, ?INVALID?", out); 
                    break;
                
                // modulation defeat
                case 5:
                    if(memcmp(out, Q5_MODULATION_DEFEAT, 5) == 0)
                        UserMessage("\r\n%s, MODULATION_DEFEAT", out);
                    else
                        UserMessage("\r\n%s, ?INVALID?", out); 
                    break;
                    
                // read
                case 6:
                    if(memcmp(out, Q5_DIRECT_ACCESS, 2) == 0)
                        UserMessage("\r\n%s, DIRECT_ACCESS:", out);
                    else
                    {
                        UserMessage("\r\n%s, ?INVALID?", out); 
                        break;
                    }
                    // PWD mode (should be 0))
                    UserMessage("%0.1s:", out + 2);
                    // ADDRESS
                    binstringtohex(tmp, out + 3);
                    UserMessage("%0.2s", tmp);
                    pwd= FALSE;
                    break;
                    
                // login (AOR followed by PWD)
                case 34:
                    if(memcmp(out, Q5_AOR, 2) == 0)
                        UserMessage("\r\n%s, AOR:", out);
                    else
                    {
                        UserMessage("\r\n%s, ?INVALID?", out); 
                        break;
                    }
                    // PWD
                    binstringtohex(tmp, out + 2);
                    UserMessage("%0.8s", tmp);
                    pwd= TRUE;
                    break;
                
                // PWD read/ STD write
                // note the only way to tell these apart is by knowing we are in PWD mode
                case 38:
                    if(pwd && memcmp(out, Q5_DIRECT_ACCESS, 2) == 0)
                    {
                        UserMessage("\r\n%s, PWD_DIRECT_ACCESS:", out);
                        // PWD
                        binstringtohex(tmp, out + 2);
                        UserMessage("%0.8s:", tmp);
                        // Lock BIT
                        UserMessage("%0.1s:", out + 34);
                        // ADDRESS
                        binstringtohex(tmp, out + 35);
                        UserMessage("%0.1s", tmp);
                        break;
                    }
                    
                    if(!pwd && memcmp(out, Q5_WRITE_P0, 2) == 0)
                        UserMessage("\r\n%s, WRITE_P0:", out);
                    else
                    {
                        UserMessage("\r\n%s, ?INVALID?", out); 
                        break;
                    }
                    // Lock BIT
                    UserMessage("%0.1s:", out + 2);
                    // DATA
                    binstringtohex(tmp, out + 3);
                    UserMessage("%0.8s:", tmp);
                    // ADDRESS
                    binstringtohex(tmp, out + 35);
                    UserMessage("%0.1s", tmp);
                    break;
                    
                // PWD write
                case 70:
                    if(memcmp(out, Q5_WRITE_P0, 2) == 0)
                        UserMessage("\r\n%s, PWD_WRITE_P0:", out);
                    else
                    {
                        UserMessage("\r\n%s, ?INVALID?", out); 
                        break;
                    }
                    // PWD
                    binstringtohex(tmp, out + 2);
                    UserMessage("%0.8s:", tmp);
                    // Lock BIT
                    UserMessage("%0.1s:", out + 34);
                    // DATA
                    binstringtohex(tmp, out + 35);
                    UserMessage("%0.8s:", tmp);
                    // ADDRESS
                    binstringtohex(tmp, out + 67);
                    UserMessage("%0.1s", tmp);
                    pwd= TRUE;
                    break;
                    
                default:
                    UserMessage("\r\n%s, ?INVALID?", out);
                    break;
            }
            decoded= TRUE;
        }
    }
    
    UserMessage("%s", "\r\n");
    
    return decoded;
}
Exemplo n.º 6
0
Arquivo: util.c Projeto: 10to7/RFIDler
// print a binstring value as hex
void printbinstringashex(unsigned char *bin)
{
    if(binstringtohex(TmpBits, bin))
        UserMessage("%s\r\n", TmpBits);
}