mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
common: fix mix of spaces & tabs
This commit is contained in:
parent
9502b54aa0
commit
23f1a253a7
|
@ -1,47 +1,47 @@
|
||||||
#include "bucketsort.h"
|
#include "bucketsort.h"
|
||||||
|
|
||||||
extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
|
extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
|
||||||
uint32_t* const ostart, uint32_t* const ostop,
|
uint32_t* const ostart, uint32_t* const ostop,
|
||||||
bucket_info_t *bucket_info, bucket_array_t bucket)
|
bucket_info_t *bucket_info, bucket_array_t bucket)
|
||||||
{
|
{
|
||||||
uint32_t *p1, *p2;
|
uint32_t *p1, *p2;
|
||||||
uint32_t *start[2];
|
uint32_t *start[2];
|
||||||
uint32_t *stop[2];
|
uint32_t *stop[2];
|
||||||
|
|
||||||
start[0] = estart;
|
start[0] = estart;
|
||||||
stop[0] = estop;
|
stop[0] = estop;
|
||||||
start[1] = ostart;
|
start[1] = ostart;
|
||||||
stop[1] = ostop;
|
stop[1] = ostop;
|
||||||
|
|
||||||
// init buckets to be empty
|
// init buckets to be empty
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
||||||
bucket[i][j].bp = bucket[i][j].head;
|
bucket[i][j].bp = bucket[i][j].head;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the lists into the buckets based on the MSB (contribution bits)
|
// sort the lists into the buckets based on the MSB (contribution bits)
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
for (p1 = start[i]; p1 <= stop[i]; p1++) {
|
for (p1 = start[i]; p1 <= stop[i]; p1++) {
|
||||||
uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
|
uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
|
||||||
*(bucket[i][bucket_index].bp++) = *p1;
|
*(bucket[i][bucket_index].bp++) = *p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write back intersecting buckets as sorted list.
|
// write back intersecting buckets as sorted list.
|
||||||
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
|
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
|
||||||
uint32_t nonempty_bucket;
|
uint32_t nonempty_bucket;
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
p1 = start[i];
|
p1 = start[i];
|
||||||
nonempty_bucket = 0;
|
nonempty_bucket = 0;
|
||||||
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
||||||
if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
|
if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
|
||||||
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
|
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
|
||||||
for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
|
for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
|
||||||
bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
|
bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
|
||||||
nonempty_bucket++;
|
nonempty_bucket++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bucket_info->numbuckets = nonempty_bucket;
|
bucket_info->numbuckets = nonempty_bucket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,20 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct bucket {
|
typedef struct bucket {
|
||||||
uint32_t *head;
|
uint32_t *head;
|
||||||
uint32_t *bp;
|
uint32_t *bp;
|
||||||
} bucket_t;
|
} bucket_t;
|
||||||
|
|
||||||
typedef bucket_t bucket_array_t[2][0x100];
|
typedef bucket_t bucket_array_t[2][0x100];
|
||||||
|
|
||||||
typedef struct bucket_info {
|
typedef struct bucket_info {
|
||||||
struct {
|
struct {
|
||||||
uint32_t *head, *tail;
|
uint32_t *head, *tail;
|
||||||
} bucket_info[2][0x100];
|
} bucket_info[2][0x100];
|
||||||
uint32_t numbuckets;
|
uint32_t numbuckets;
|
||||||
} bucket_info_t;
|
} bucket_info_t;
|
||||||
|
|
||||||
void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
|
void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
|
||||||
uint32_t* const ostart, uint32_t* const ostop,
|
uint32_t* const ostart, uint32_t* const ostop,
|
||||||
bucket_info_t *bucket_info, bucket_array_t bucket);
|
bucket_info_t *bucket_info, bucket_array_t bucket);
|
||||||
#endif
|
#endif
|
42
common/cmd.c
42
common/cmd.c
|
@ -32,33 +32,33 @@
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
||||||
UsbCommand txcmd;
|
UsbCommand txcmd;
|
||||||
|
|
||||||
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
||||||
((uint8_t*)&txcmd)[i] = 0x00;
|
((uint8_t*)&txcmd)[i] = 0x00;
|
||||||
|
|
||||||
// Compose the outgoing command frame
|
// Compose the outgoing command frame
|
||||||
txcmd.cmd = cmd;
|
txcmd.cmd = cmd;
|
||||||
txcmd.arg[0] = arg0;
|
txcmd.arg[0] = arg0;
|
||||||
txcmd.arg[1] = arg1;
|
txcmd.arg[1] = arg1;
|
||||||
txcmd.arg[2] = arg2;
|
txcmd.arg[2] = arg2;
|
||||||
|
|
||||||
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
|
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
|
||||||
if (data && len) {
|
if (data && len) {
|
||||||
len = MIN(len, USB_CMD_DATA_SIZE);
|
len = MIN(len, USB_CMD_DATA_SIZE);
|
||||||
for (size_t i=0; i<len; i++) {
|
for (size_t i=0; i<len; i++) {
|
||||||
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sendlen = 0;
|
uint32_t sendlen = 0;
|
||||||
// Send frame and make sure all bytes are transmitted
|
// Send frame and make sure all bytes are transmitted
|
||||||
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||||
|
|
||||||
#ifdef WITH_FPC
|
#ifdef WITH_FPC
|
||||||
// usart_init();
|
// usart_init();
|
||||||
// usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
// usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sendlen;
|
return sendlen;
|
||||||
}
|
}
|
|
@ -1,19 +1,19 @@
|
||||||
/* crapto1.c
|
/* crapto1.c
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
as published by the Free Software Foundation; either version 2
|
as published by the Free Software Foundation; either version 2
|
||||||
of the License, or (at your option) any later version.
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
Boston, MA 02110-1301, US$
|
Boston, MA 02110-1301, US$
|
||||||
|
|
||||||
Copyright (C) 2008-2014 bla <blapost@gmail.com>
|
Copyright (C) 2008-2014 bla <blapost@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -26,9 +26,9 @@
|
||||||
static uint8_t filterlut[1 << 20];
|
static uint8_t filterlut[1 << 20];
|
||||||
static void __attribute__((constructor)) fill_lut()
|
static void __attribute__((constructor)) fill_lut()
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0; i < 1 << 20; ++i)
|
for(i = 0; i < 1 << 20; ++i)
|
||||||
filterlut[i] = filter(i);
|
filterlut[i] = filter(i);
|
||||||
}
|
}
|
||||||
#define filter(x) (filterlut[(x) & 0xfffff])
|
#define filter(x) (filterlut[(x) & 0xfffff])
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,11 +38,11 @@ static void __attribute__((constructor)) fill_lut()
|
||||||
*/
|
*/
|
||||||
static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
|
static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
|
||||||
{
|
{
|
||||||
uint32_t p = *item >> 25;
|
uint32_t p = *item >> 25;
|
||||||
|
|
||||||
p = p << 1 | evenparity32(*item & mask1);
|
p = p << 1 | evenparity32(*item & mask1);
|
||||||
p = p << 1 | evenparity32(*item & mask2);
|
p = p << 1 | evenparity32(*item & mask2);
|
||||||
*item = p << 24 | (*item & 0xffffff);
|
*item = p << 24 | (*item & 0xffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** extend_table
|
/** extend_table
|
||||||
|
@ -50,83 +50,83 @@ static inline void update_contribution(uint32_t *item, const uint32_t mask1, con
|
||||||
*/
|
*/
|
||||||
static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
|
static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
|
||||||
{
|
{
|
||||||
in <<= 24;
|
in <<= 24;
|
||||||
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
|
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
|
||||||
if(filter(*tbl) ^ filter(*tbl | 1)) {
|
if(filter(*tbl) ^ filter(*tbl | 1)) {
|
||||||
*tbl |= filter(*tbl) ^ bit;
|
*tbl |= filter(*tbl) ^ bit;
|
||||||
update_contribution(tbl, m1, m2);
|
update_contribution(tbl, m1, m2);
|
||||||
*tbl ^= in;
|
*tbl ^= in;
|
||||||
} else if(filter(*tbl) == bit) {
|
} else if(filter(*tbl) == bit) {
|
||||||
*++*end = tbl[1];
|
*++*end = tbl[1];
|
||||||
tbl[1] = tbl[0] | 1;
|
tbl[1] = tbl[0] | 1;
|
||||||
update_contribution(tbl, m1, m2);
|
update_contribution(tbl, m1, m2);
|
||||||
*tbl++ ^= in;
|
*tbl++ ^= in;
|
||||||
update_contribution(tbl, m1, m2);
|
update_contribution(tbl, m1, m2);
|
||||||
*tbl ^= in;
|
*tbl ^= in;
|
||||||
} else
|
} else
|
||||||
*tbl-- = *(*end)--;
|
*tbl-- = *(*end)--;
|
||||||
}
|
}
|
||||||
/** extend_table_simple
|
/** extend_table_simple
|
||||||
* using a bit of the keystream extend the table of possible lfsr states
|
* using a bit of the keystream extend the table of possible lfsr states
|
||||||
*/
|
*/
|
||||||
static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
|
static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
|
||||||
{
|
{
|
||||||
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) {
|
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) {
|
||||||
if(filter(*tbl) ^ filter(*tbl | 1)) { // replace
|
if(filter(*tbl) ^ filter(*tbl | 1)) { // replace
|
||||||
*tbl |= filter(*tbl) ^ bit;
|
*tbl |= filter(*tbl) ^ bit;
|
||||||
} else if(filter(*tbl) == bit) { // insert
|
} else if(filter(*tbl) == bit) { // insert
|
||||||
*++*end = *++tbl;
|
*++*end = *++tbl;
|
||||||
*tbl = tbl[-1] | 1;
|
*tbl = tbl[-1] | 1;
|
||||||
} else { // drop
|
} else { // drop
|
||||||
*tbl-- = *(*end)--;
|
*tbl-- = *(*end)--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** recover
|
/** recover
|
||||||
* recursively narrow down the search space, 4 bits of keystream at a time
|
* recursively narrow down the search space, 4 bits of keystream at a time
|
||||||
*/
|
*/
|
||||||
static struct Crypto1State*
|
static struct Crypto1State*
|
||||||
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
||||||
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
|
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
|
||||||
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
|
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
|
||||||
{
|
{
|
||||||
uint32_t *o, *e;
|
uint32_t *o, *e;
|
||||||
bucket_info_t bucket_info;
|
bucket_info_t bucket_info;
|
||||||
|
|
||||||
if(rem == -1) {
|
if(rem == -1) {
|
||||||
for(e = e_head; e <= e_tail; ++e) {
|
for(e = e_head; e <= e_tail; ++e) {
|
||||||
*e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4);
|
*e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4);
|
||||||
for(o = o_head; o <= o_tail; ++o, ++sl) {
|
for(o = o_head; o <= o_tail; ++o, ++sl) {
|
||||||
sl->even = *o;
|
sl->even = *o;
|
||||||
sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD);
|
sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD);
|
||||||
sl[1].odd = sl[1].even = 0;
|
sl[1].odd = sl[1].even = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sl;
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint32_t i = 0; i < 4 && rem--; i++) {
|
for(uint32_t i = 0; i < 4 && rem--; i++) {
|
||||||
oks >>= 1;
|
oks >>= 1;
|
||||||
eks >>= 1;
|
eks >>= 1;
|
||||||
in >>= 2;
|
in >>= 2;
|
||||||
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
|
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
|
||||||
if(o_head > o_tail)
|
if(o_head > o_tail)
|
||||||
return sl;
|
return sl;
|
||||||
|
|
||||||
extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3);
|
extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3);
|
||||||
if(e_head > e_tail)
|
if(e_head > e_tail)
|
||||||
return sl;
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);
|
bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);
|
||||||
|
|
||||||
for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {
|
for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {
|
||||||
sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,
|
sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,
|
||||||
bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,
|
bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,
|
||||||
rem, sl, in, bucket);
|
rem, sl, in, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sl;
|
return sl;
|
||||||
}
|
}
|
||||||
/** lfsr_recovery
|
/** lfsr_recovery
|
||||||
* recover the state of the lfsr given 32 bits of the keystream
|
* recover the state of the lfsr given 32 bits of the keystream
|
||||||
|
@ -135,87 +135,87 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
||||||
*/
|
*/
|
||||||
struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
|
struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
|
||||||
{
|
{
|
||||||
struct Crypto1State *statelist;
|
struct Crypto1State *statelist;
|
||||||
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
|
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
|
||||||
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
|
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// split the keystream into an odd and even part
|
// split the keystream into an odd and even part
|
||||||
for (i = 31; i >= 0; i -= 2)
|
for (i = 31; i >= 0; i -= 2)
|
||||||
oks = oks << 1 | BEBIT(ks2, i);
|
oks = oks << 1 | BEBIT(ks2, i);
|
||||||
for (i = 30; i >= 0; i -= 2)
|
for (i = 30; i >= 0; i -= 2)
|
||||||
eks = eks << 1 | BEBIT(ks2, i);
|
eks = eks << 1 | BEBIT(ks2, i);
|
||||||
|
|
||||||
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
|
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
|
||||||
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
|
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
|
||||||
statelist = malloc(sizeof(struct Crypto1State) << 18);
|
statelist = malloc(sizeof(struct Crypto1State) << 18);
|
||||||
if (!odd_tail-- || !even_tail-- || !statelist) {
|
if (!odd_tail-- || !even_tail-- || !statelist) {
|
||||||
free(statelist);
|
free(statelist);
|
||||||
statelist = 0;
|
statelist = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
statelist->odd = statelist->even = 0;
|
statelist->odd = statelist->even = 0;
|
||||||
|
|
||||||
// allocate memory for out of place bucket_sort
|
// allocate memory for out of place bucket_sort
|
||||||
bucket_array_t bucket;
|
bucket_array_t bucket;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
for (uint32_t j = 0; j <= 0xff; j++) {
|
for (uint32_t j = 0; j <= 0xff; j++) {
|
||||||
bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
|
bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
|
||||||
if (!bucket[i][j].head) {
|
if (!bucket[i][j].head) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
|
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
|
||||||
for(i = 1 << 20; i >= 0; --i) {
|
for(i = 1 << 20; i >= 0; --i) {
|
||||||
if(filter(i) == (oks & 1))
|
if(filter(i) == (oks & 1))
|
||||||
*++odd_tail = i;
|
*++odd_tail = i;
|
||||||
if(filter(i) == (eks & 1))
|
if(filter(i) == (eks & 1))
|
||||||
*++even_tail = i;
|
*++even_tail = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
|
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
|
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
|
||||||
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
|
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the statelists now contain all states which could have generated the last 10 Bits of the keystream.
|
// the statelists now contain all states which could have generated the last 10 Bits of the keystream.
|
||||||
// 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"
|
// 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"
|
||||||
// parameter into account.
|
// parameter into account.
|
||||||
in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping
|
in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping
|
||||||
recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket);
|
recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for (uint32_t i = 0; i < 2; i++)
|
for (uint32_t i = 0; i < 2; i++)
|
||||||
for (uint32_t j = 0; j <= 0xff; j++)
|
for (uint32_t j = 0; j <= 0xff; j++)
|
||||||
free(bucket[i][j].head);
|
free(bucket[i][j].head);
|
||||||
free(odd_head);
|
free(odd_head);
|
||||||
free(even_head);
|
free(even_head);
|
||||||
return statelist;
|
return statelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
|
static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
|
||||||
0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
|
0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
|
||||||
0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
|
0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
|
||||||
static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
|
static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
|
||||||
0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
|
0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
|
||||||
0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
|
0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
|
||||||
0x7EC7EE90, 0x7F63F748, 0x79117020};
|
0x7EC7EE90, 0x7F63F748, 0x79117020};
|
||||||
static const uint32_t T1[] = {
|
static const uint32_t T1[] = {
|
||||||
0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
|
0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
|
||||||
0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
|
0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
|
||||||
0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
|
0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
|
||||||
0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
|
0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
|
||||||
static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
|
static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
|
||||||
0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
|
0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
|
||||||
0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
|
0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
|
||||||
0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
|
0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
|
||||||
0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
|
0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
|
||||||
0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
|
0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
|
||||||
static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
|
static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
|
||||||
static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
|
static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
|
||||||
/** Reverse 64 bits of keystream into possible cipher states
|
/** Reverse 64 bits of keystream into possible cipher states
|
||||||
|
@ -223,69 +223,69 @@ static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
|
||||||
*/
|
*/
|
||||||
struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
|
struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
|
||||||
{
|
{
|
||||||
struct Crypto1State *statelist, *sl;
|
struct Crypto1State *statelist, *sl;
|
||||||
uint8_t oks[32], eks[32], hi[32];
|
uint8_t oks[32], eks[32], hi[32];
|
||||||
uint32_t low = 0, win = 0;
|
uint32_t low = 0, win = 0;
|
||||||
uint32_t *tail, table[1 << 16];
|
uint32_t *tail, table[1 << 16];
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
|
sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
|
||||||
if(!sl)
|
if(!sl)
|
||||||
return 0;
|
return 0;
|
||||||
sl->odd = sl->even = 0;
|
sl->odd = sl->even = 0;
|
||||||
|
|
||||||
for(i = 30; i >= 0; i -= 2) {
|
for(i = 30; i >= 0; i -= 2) {
|
||||||
oks[i >> 1] = BEBIT(ks2, i);
|
oks[i >> 1] = BEBIT(ks2, i);
|
||||||
oks[16 + (i >> 1)] = BEBIT(ks3, i);
|
oks[16 + (i >> 1)] = BEBIT(ks3, i);
|
||||||
}
|
}
|
||||||
for(i = 31; i >= 0; i -= 2) {
|
for(i = 31; i >= 0; i -= 2) {
|
||||||
eks[i >> 1] = BEBIT(ks2, i);
|
eks[i >> 1] = BEBIT(ks2, i);
|
||||||
eks[16 + (i >> 1)] = BEBIT(ks3, i);
|
eks[16 + (i >> 1)] = BEBIT(ks3, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0xfffff; i >= 0; --i) {
|
for(i = 0xfffff; i >= 0; --i) {
|
||||||
if (filter(i) != oks[0])
|
if (filter(i) != oks[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*(tail = table) = i;
|
*(tail = table) = i;
|
||||||
for(j = 1; tail >= table && j < 29; ++j)
|
for(j = 1; tail >= table && j < 29; ++j)
|
||||||
extend_table_simple(table, &tail, oks[j]);
|
extend_table_simple(table, &tail, oks[j]);
|
||||||
|
|
||||||
if(tail < table)
|
if(tail < table)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(j = 0; j < 19; ++j)
|
for(j = 0; j < 19; ++j)
|
||||||
low = low << 1 | evenparity32(i & S1[j]);
|
low = low << 1 | evenparity32(i & S1[j]);
|
||||||
for(j = 0; j < 32; ++j)
|
for(j = 0; j < 32; ++j)
|
||||||
hi[j] = evenparity32(i & T1[j]);
|
hi[j] = evenparity32(i & T1[j]);
|
||||||
|
|
||||||
for(; tail >= table; --tail) {
|
for(; tail >= table; --tail) {
|
||||||
for(j = 0; j < 3; ++j) {
|
for(j = 0; j < 3; ++j) {
|
||||||
*tail = *tail << 1;
|
*tail = *tail << 1;
|
||||||
*tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j]));
|
*tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j]));
|
||||||
if(filter(*tail) != oks[29 + j])
|
if(filter(*tail) != oks[29 + j])
|
||||||
goto continue2;
|
goto continue2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(j = 0; j < 19; ++j)
|
for(j = 0; j < 19; ++j)
|
||||||
win = win << 1 | evenparity32(*tail & S2[j]);
|
win = win << 1 | evenparity32(*tail & S2[j]);
|
||||||
|
|
||||||
win ^= low;
|
win ^= low;
|
||||||
for(j = 0; j < 32; ++j) {
|
for(j = 0; j < 32; ++j) {
|
||||||
win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]);
|
win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]);
|
||||||
if(filter(win) != eks[j])
|
if(filter(win) != eks[j])
|
||||||
goto continue2;
|
goto continue2;
|
||||||
}
|
}
|
||||||
|
|
||||||
*tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail);
|
*tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail);
|
||||||
sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win);
|
sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win);
|
||||||
sl->even = win;
|
sl->even = win;
|
||||||
++sl;
|
++sl;
|
||||||
sl->odd = sl->even = 0;
|
sl->odd = sl->even = 0;
|
||||||
continue2:;
|
continue2:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return statelist;
|
return statelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** lfsr_rollback_bit
|
/** lfsr_rollback_bit
|
||||||
|
@ -293,37 +293,37 @@ struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
|
||||||
*/
|
*/
|
||||||
uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
|
uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
|
||||||
{
|
{
|
||||||
int out;
|
int out;
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
uint32_t t;
|
uint32_t t;
|
||||||
|
|
||||||
s->odd &= 0xffffff;
|
s->odd &= 0xffffff;
|
||||||
t = s->odd, s->odd = s->even, s->even = t;
|
t = s->odd, s->odd = s->even, s->even = t;
|
||||||
|
|
||||||
out = s->even & 1;
|
out = s->even & 1;
|
||||||
out ^= LF_POLY_EVEN & (s->even >>= 1);
|
out ^= LF_POLY_EVEN & (s->even >>= 1);
|
||||||
out ^= LF_POLY_ODD & s->odd;
|
out ^= LF_POLY_ODD & s->odd;
|
||||||
out ^= !!in;
|
out ^= !!in;
|
||||||
out ^= (ret = filter(s->odd)) & !!fb;
|
out ^= (ret = filter(s->odd)) & !!fb;
|
||||||
|
|
||||||
s->even |= evenparity32(out) << 23;
|
s->even |= evenparity32(out) << 23;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/** lfsr_rollback_byte
|
/** lfsr_rollback_byte
|
||||||
* Rollback the shift register in order to get previous states
|
* Rollback the shift register in order to get previous states
|
||||||
*/
|
*/
|
||||||
uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
|
uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
|
||||||
{
|
{
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7;
|
ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6;
|
ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5;
|
ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4;
|
ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3;
|
ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2;
|
ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;
|
ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;
|
||||||
ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;
|
ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/** lfsr_rollback_word
|
/** lfsr_rollback_word
|
||||||
* Rollback the shift register in order to get previous states
|
* Rollback the shift register in order to get previous states
|
||||||
|
@ -331,43 +331,43 @@ uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
|
||||||
uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
|
uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24);
|
||||||
|
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24);
|
||||||
|
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24);
|
||||||
|
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24);
|
||||||
ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);
|
ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** nonce_distance
|
/** nonce_distance
|
||||||
|
@ -376,17 +376,17 @@ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
|
||||||
static uint16_t *dist = 0;
|
static uint16_t *dist = 0;
|
||||||
int nonce_distance(uint32_t from, uint32_t to)
|
int nonce_distance(uint32_t from, uint32_t to)
|
||||||
{
|
{
|
||||||
uint16_t x, i;
|
uint16_t x, i;
|
||||||
if(!dist) {
|
if(!dist) {
|
||||||
dist = calloc(2 << 16, sizeof(uint8_t));
|
dist = calloc(2 << 16, sizeof(uint8_t));
|
||||||
if(!dist)
|
if(!dist)
|
||||||
return -1;
|
return -1;
|
||||||
for (x = i = 1; i; ++i) {
|
for (x = i = 1; i; ++i) {
|
||||||
dist[(x & 0xff) << 8 | x >> 8] = i;
|
dist[(x & 0xff) << 8 | x >> 8] = i;
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
|
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** validate_prng_nonce
|
/** validate_prng_nonce
|
||||||
|
@ -396,14 +396,14 @@ int nonce_distance(uint32_t from, uint32_t to)
|
||||||
* false = hardend prng
|
* false = hardend prng
|
||||||
*/
|
*/
|
||||||
bool validate_prng_nonce(uint32_t nonce) {
|
bool validate_prng_nonce(uint32_t nonce) {
|
||||||
// init prng table:
|
// init prng table:
|
||||||
nonce_distance(nonce, nonce);
|
nonce_distance(nonce, nonce);
|
||||||
return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16;
|
return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t fastfwd[2][8] = {
|
static uint32_t fastfwd[2][8] = {
|
||||||
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
|
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
|
||||||
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
|
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
|
||||||
|
|
||||||
/** lfsr_prefix_ks
|
/** lfsr_prefix_ks
|
||||||
*
|
*
|
||||||
|
@ -416,25 +416,25 @@ static uint32_t fastfwd[2][8] = {
|
||||||
*/
|
*/
|
||||||
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
|
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
|
||||||
{
|
{
|
||||||
uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t));
|
uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t));
|
||||||
if (!candidates) return 0;
|
if (!candidates) return 0;
|
||||||
|
|
||||||
uint32_t c, entry;
|
uint32_t c, entry;
|
||||||
int size = 0, i, good;
|
int size = 0, i, good;
|
||||||
|
|
||||||
for (i = 0; i < 1 << 21; ++i) {
|
for (i = 0; i < 1 << 21; ++i) {
|
||||||
for (c = 0, good = 1; good && c < 8; ++c) {
|
for (c = 0, good = 1; good && c < 8; ++c) {
|
||||||
entry = i ^ fastfwd[isodd][c];
|
entry = i ^ fastfwd[isodd][c];
|
||||||
good &= (BIT(ks[c], isodd) == filter(entry >> 1));
|
good &= (BIT(ks[c], isodd) == filter(entry >> 1));
|
||||||
good &= (BIT(ks[c], isodd + 2) == filter(entry));
|
good &= (BIT(ks[c], isodd + 2) == filter(entry));
|
||||||
}
|
}
|
||||||
if (good)
|
if (good)
|
||||||
candidates[size++] = i;
|
candidates[size++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates[size] = -1;
|
candidates[size] = -1;
|
||||||
|
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check_pfx_parity
|
/** check_pfx_parity
|
||||||
|
@ -442,33 +442,33 @@ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
|
||||||
*/
|
*/
|
||||||
static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State* sl, uint32_t no_par)
|
static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State* sl, uint32_t no_par)
|
||||||
{
|
{
|
||||||
uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
|
uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
|
||||||
|
|
||||||
for(c = 0; good && c < 8; ++c) {
|
for(c = 0; good && c < 8; ++c) {
|
||||||
sl->odd = odd ^ fastfwd[1][c];
|
sl->odd = odd ^ fastfwd[1][c];
|
||||||
sl->even = even ^ fastfwd[0][c];
|
sl->even = even ^ fastfwd[0][c];
|
||||||
|
|
||||||
lfsr_rollback_bit(sl, 0, 0);
|
lfsr_rollback_bit(sl, 0, 0);
|
||||||
lfsr_rollback_bit(sl, 0, 0);
|
lfsr_rollback_bit(sl, 0, 0);
|
||||||
|
|
||||||
ks3 = lfsr_rollback_bit(sl, 0, 0);
|
ks3 = lfsr_rollback_bit(sl, 0, 0);
|
||||||
ks2 = lfsr_rollback_word(sl, 0, 0);
|
ks2 = lfsr_rollback_word(sl, 0, 0);
|
||||||
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
|
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
|
||||||
|
|
||||||
if (no_par)
|
if (no_par)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nr = ks1 ^ (prefix | c << 5);
|
nr = ks1 ^ (prefix | c << 5);
|
||||||
rr = ks2 ^ rresp;
|
rr = ks2 ^ rresp;
|
||||||
|
|
||||||
good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
|
good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
|
||||||
good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
|
good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
|
||||||
good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
|
good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
|
||||||
good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
|
good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
|
||||||
good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
|
good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sl + good;
|
return sl + good;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,30 +484,30 @@ static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, ui
|
||||||
|
|
||||||
struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par)
|
struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par)
|
||||||
{
|
{
|
||||||
struct Crypto1State *statelist, *s;
|
struct Crypto1State *statelist, *s;
|
||||||
uint32_t *odd, *even, *o, *e, top;
|
uint32_t *odd, *even, *o, *e, top;
|
||||||
|
|
||||||
odd = lfsr_prefix_ks(ks, 1);
|
odd = lfsr_prefix_ks(ks, 1);
|
||||||
even = lfsr_prefix_ks(ks, 0);
|
even = lfsr_prefix_ks(ks, 0);
|
||||||
|
|
||||||
s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
|
s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
|
||||||
if (!s || !odd || !even) {
|
if (!s || !odd || !even) {
|
||||||
free(statelist);
|
free(statelist);
|
||||||
statelist = 0;
|
statelist = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (o = odd; *o + 1; ++o)
|
for (o = odd; *o + 1; ++o)
|
||||||
for (e = even; *e + 1; ++e)
|
for (e = even; *e + 1; ++e)
|
||||||
for (top = 0; top < 64; ++top) {
|
for (top = 0; top < 64; ++top) {
|
||||||
*o += 1 << 21;
|
*o += 1 << 21;
|
||||||
*e += (!(top & 7) + 1) << 21;
|
*e += (!(top & 7) + 1) << 21;
|
||||||
s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
|
s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->odd = s->even = 0;
|
s->odd = s->even = 0;
|
||||||
out:
|
out:
|
||||||
free(odd);
|
free(odd);
|
||||||
free(even);
|
free(even);
|
||||||
return statelist;
|
return statelist;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Crypto1State {uint32_t odd, even;};
|
struct Crypto1State {uint32_t odd, even;};
|
||||||
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||||
void crypto1_create(struct Crypto1State *s, uint64_t key);
|
void crypto1_create(struct Crypto1State *s, uint64_t key);
|
||||||
#else
|
#else
|
||||||
struct Crypto1State *crypto1_create(uint64_t key);
|
struct Crypto1State *crypto1_create(uint64_t key);
|
||||||
|
@ -53,15 +53,15 @@ uint32_t lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
|
||||||
int nonce_distance(uint32_t from, uint32_t to);
|
int nonce_distance(uint32_t from, uint32_t to);
|
||||||
extern bool validate_prng_nonce(uint32_t nonce);
|
extern bool validate_prng_nonce(uint32_t nonce);
|
||||||
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
|
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
|
||||||
uint32_t __n = 0,__M = 0, N = 0;\
|
uint32_t __n = 0,__M = 0, N = 0;\
|
||||||
int __i;\
|
int __i;\
|
||||||
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
|
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
|
||||||
for(__i = FSIZE - 1; __i >= 0; __i--)\
|
for(__i = FSIZE - 1; __i >= 0; __i--)\
|
||||||
if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
|
if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
|
||||||
break;\
|
break;\
|
||||||
else if(__i)\
|
else if(__i)\
|
||||||
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\
|
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\
|
||||||
else
|
else
|
||||||
|
|
||||||
#define LF_POLY_ODD (0x29CE5C)
|
#define LF_POLY_ODD (0x29CE5C)
|
||||||
#define LF_POLY_EVEN (0x870804)
|
#define LF_POLY_EVEN (0x870804)
|
||||||
|
@ -69,14 +69,14 @@ extern bool validate_prng_nonce(uint32_t nonce);
|
||||||
#define BEBIT(x, n) BIT(x, (n) ^ 24)
|
#define BEBIT(x, n) BIT(x, (n) ^ 24)
|
||||||
static inline int filter(uint32_t const x)
|
static inline int filter(uint32_t const x)
|
||||||
{
|
{
|
||||||
uint32_t f;
|
uint32_t f;
|
||||||
|
|
||||||
f = 0xf22c0 >> (x & 0xf) & 16;
|
f = 0xf22c0 >> (x & 0xf) & 16;
|
||||||
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
|
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
|
||||||
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
|
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
|
||||||
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
|
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
|
||||||
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
|
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
|
||||||
return BIT(0xEC57E80A, f);
|
return BIT(0xEC57E80A, f);
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
/* crypto1.c
|
/* crypto1.c
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
as published by the Free Software Foundation; either version 2
|
as published by the Free Software Foundation; either version 2
|
||||||
of the License, or (at your option) any later version.
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
MA 02110-1301, US
|
MA 02110-1301, US
|
||||||
|
|
||||||
Copyright (C) 2008-2008 bla <blapost@gmail.com>
|
Copyright (C) 2008-2008 bla <blapost@gmail.com>
|
||||||
*/
|
*/
|
||||||
#include "crapto1.h"
|
#include "crapto1.h"
|
||||||
|
|
||||||
|
@ -23,121 +23,121 @@
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
|
|
||||||
#define SWAPENDIAN(x)\
|
#define SWAPENDIAN(x)\
|
||||||
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
|
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
|
||||||
|
|
||||||
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||||
void crypto1_create(struct Crypto1State *s, uint64_t key)
|
void crypto1_create(struct Crypto1State *s, uint64_t key)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 47;s && i > 0; i -= 2) {
|
for(i = 47;s && i > 0; i -= 2) {
|
||||||
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
||||||
s->even = s->even << 1 | BIT(key, i ^ 7);
|
s->even = s->even << 1 | BIT(key, i ^ 7);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void crypto1_destroy(struct Crypto1State *state)
|
void crypto1_destroy(struct Crypto1State *state)
|
||||||
{
|
{
|
||||||
state->odd = 0;
|
state->odd = 0;
|
||||||
state->even = 0;
|
state->even = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct Crypto1State * crypto1_create(uint64_t key)
|
struct Crypto1State * crypto1_create(uint64_t key)
|
||||||
{
|
{
|
||||||
struct Crypto1State *s = malloc(sizeof(*s));
|
struct Crypto1State *s = malloc(sizeof(*s));
|
||||||
if ( !s ) return NULL;
|
if ( !s ) return NULL;
|
||||||
|
|
||||||
s->odd = s->even = 0;
|
s->odd = s->even = 0;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 47; i > 0; i -= 2) {
|
for(i = 47; i > 0; i -= 2) {
|
||||||
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
||||||
s->even = s->even << 1 | BIT(key, i ^ 7);
|
s->even = s->even << 1 | BIT(key, i ^ 7);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
void crypto1_destroy(struct Crypto1State *state)
|
void crypto1_destroy(struct Crypto1State *state)
|
||||||
{
|
{
|
||||||
free(state);
|
free(state);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
|
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(*lfsr = 0, i = 23; i >= 0; --i) {
|
for(*lfsr = 0, i = 23; i >= 0; --i) {
|
||||||
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
|
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
|
||||||
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
|
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
|
uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
|
||||||
{
|
{
|
||||||
uint32_t feedin, t;
|
uint32_t feedin, t;
|
||||||
uint8_t ret = filter(s->odd);
|
uint8_t ret = filter(s->odd);
|
||||||
|
|
||||||
feedin = ret & !!is_encrypted;
|
feedin = ret & !!is_encrypted;
|
||||||
feedin ^= !!in;
|
feedin ^= !!in;
|
||||||
feedin ^= LF_POLY_ODD & s->odd;
|
feedin ^= LF_POLY_ODD & s->odd;
|
||||||
feedin ^= LF_POLY_EVEN & s->even;
|
feedin ^= LF_POLY_EVEN & s->even;
|
||||||
s->even = s->even << 1 | evenparity32(feedin);
|
s->even = s->even << 1 | evenparity32(feedin);
|
||||||
|
|
||||||
t = s->odd;
|
t = s->odd;
|
||||||
s->odd = s->even;
|
s->odd = s->even;
|
||||||
s->even = t;
|
s->even = t;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
|
uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
|
||||||
{
|
{
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0;
|
ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0;
|
||||||
ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1;
|
ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1;
|
||||||
ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2;
|
ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2;
|
||||||
ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3;
|
ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3;
|
||||||
ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4;
|
ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4;
|
||||||
ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5;
|
ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5;
|
||||||
ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6;
|
ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6;
|
||||||
ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7;
|
ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
|
uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
|
||||||
{
|
{
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (2 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (2 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (3 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (3 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (4 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (4 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24);
|
||||||
|
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (11 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (11 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (12 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (12 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (13 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (13 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (14 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (14 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 24);
|
||||||
|
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (16 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (16 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (17 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (17 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (18 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (18 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (19 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (19 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (20 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (20 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (21 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (21 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (22 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (22 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 24);
|
||||||
|
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (25 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (25 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (26 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (26 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (27 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (27 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (28 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (28 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (29 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (29 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24);
|
||||||
ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24);
|
ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prng_successor
|
/* prng_successor
|
||||||
|
@ -145,9 +145,9 @@ uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
|
||||||
*/
|
*/
|
||||||
uint32_t prng_successor(uint32_t x, uint32_t n)
|
uint32_t prng_successor(uint32_t x, uint32_t n)
|
||||||
{
|
{
|
||||||
SWAPENDIAN(x);
|
SWAPENDIAN(x);
|
||||||
while(n--)
|
while(n--)
|
||||||
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
|
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
|
||||||
|
|
||||||
return SWAPENDIAN(x);
|
return SWAPENDIAN(x);
|
||||||
}
|
}
|
||||||
|
|
146
common/crc.c
146
common/crc.c
|
@ -10,118 +10,118 @@
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) {
|
void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) {
|
||||||
crc_init(crc, order, polynom, initial_value, final_xor);
|
crc_init(crc, order, polynom, initial_value, final_xor);
|
||||||
crc->refin = refin;
|
crc->refin = refin;
|
||||||
crc->refout = refout;
|
crc->refout = refout;
|
||||||
crc_clear(crc);
|
crc_clear(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) {
|
void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) {
|
||||||
crc->order = order;
|
crc->order = order;
|
||||||
crc->topbit = BITMASK( order-1 );
|
crc->topbit = BITMASK( order-1 );
|
||||||
crc->polynom = polynom;
|
crc->polynom = polynom;
|
||||||
crc->initial_value = initial_value;
|
crc->initial_value = initial_value;
|
||||||
crc->final_xor = final_xor;
|
crc->final_xor = final_xor;
|
||||||
crc->mask = (1L<<order)-1;
|
crc->mask = (1L<<order)-1;
|
||||||
crc->refin = false;
|
crc->refin = false;
|
||||||
crc->refout = false;
|
crc->refout = false;
|
||||||
crc_clear(crc);
|
crc_clear(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void crc_clear(crc_t *crc) {
|
void crc_clear(crc_t *crc) {
|
||||||
|
|
||||||
crc->state = crc->initial_value & crc->mask;
|
crc->state = crc->initial_value & crc->mask;
|
||||||
if (crc->refin)
|
if (crc->refin)
|
||||||
crc->state = reflect(crc->state, crc->order);
|
crc->state = reflect(crc->state, crc->order);
|
||||||
}
|
}
|
||||||
|
|
||||||
void crc_update2(crc_t *crc, uint32_t data, int data_width){
|
void crc_update2(crc_t *crc, uint32_t data, int data_width){
|
||||||
|
|
||||||
if (crc->refin)
|
if (crc->refin)
|
||||||
data = reflect(data, data_width);
|
data = reflect(data, data_width);
|
||||||
|
|
||||||
// Bring the next byte into the remainder.
|
// Bring the next byte into the remainder.
|
||||||
crc->state ^= data << (crc->order - data_width);
|
crc->state ^= data << (crc->order - data_width);
|
||||||
|
|
||||||
for( uint8_t bit = data_width; bit > 0; --bit) {
|
for( uint8_t bit = data_width; bit > 0; --bit) {
|
||||||
|
|
||||||
if (crc->state & crc->topbit)
|
if (crc->state & crc->topbit)
|
||||||
crc->state = (crc->state << 1) ^ crc->polynom;
|
crc->state = (crc->state << 1) ^ crc->polynom;
|
||||||
else
|
else
|
||||||
crc->state = (crc->state << 1);
|
crc->state = (crc->state << 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void crc_update(crc_t *crc, uint32_t data, int data_width)
|
void crc_update(crc_t *crc, uint32_t data, int data_width)
|
||||||
{
|
{
|
||||||
if (crc->refin)
|
if (crc->refin)
|
||||||
data = reflect(data, data_width);
|
data = reflect(data, data_width);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<data_width; i++) {
|
for(i=0; i<data_width; i++) {
|
||||||
int oldstate = crc->state;
|
int oldstate = crc->state;
|
||||||
crc->state = crc->state >> 1;
|
crc->state = crc->state >> 1;
|
||||||
if( (oldstate^data) & 1 ) {
|
if( (oldstate^data) & 1 ) {
|
||||||
crc->state ^= crc->polynom;
|
crc->state ^= crc->polynom;
|
||||||
}
|
}
|
||||||
data >>= 1;
|
data >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t crc_finish(crc_t *crc) {
|
uint32_t crc_finish(crc_t *crc) {
|
||||||
uint32_t val = crc->state;
|
uint32_t val = crc->state;
|
||||||
if (crc->refout)
|
if (crc->refout)
|
||||||
val = reflect(val, crc->order);
|
val = reflect(val, crc->order);
|
||||||
return ( val ^ crc->final_xor ) & crc->mask;
|
return ( val ^ crc->final_xor ) & crc->mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static void print_crc(crc_t *crc) {
|
static void print_crc(crc_t *crc) {
|
||||||
printf(" Order %d\n Poly %x\n Init %x\n Final %x\n Mask %x\n topbit %x\n RefIn %s\n RefOut %s\n State %x\n",
|
printf(" Order %d\n Poly %x\n Init %x\n Final %x\n Mask %x\n topbit %x\n RefIn %s\n RefOut %s\n State %x\n",
|
||||||
crc->order,
|
crc->order,
|
||||||
crc->polynom,
|
crc->polynom,
|
||||||
crc->initial_value,
|
crc->initial_value,
|
||||||
crc->final_xor,
|
crc->final_xor,
|
||||||
crc->mask,
|
crc->mask,
|
||||||
crc->topbit,
|
crc->topbit,
|
||||||
(crc->refin) ? "TRUE":"FALSE",
|
(crc->refin) ? "TRUE":"FALSE",
|
||||||
(crc->refout) ? "TRUE":"FALSE",
|
(crc->refout) ? "TRUE":"FALSE",
|
||||||
crc->state
|
crc->state
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xA1 name="CRC-8/MAXIM"
|
// width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xA1 name="CRC-8/MAXIM"
|
||||||
uint32_t CRC8Maxim(uint8_t *buff, size_t size) {
|
uint32_t CRC8Maxim(uint8_t *buff, size_t size) {
|
||||||
crc_t crc;
|
crc_t crc;
|
||||||
crc_init_ref(&crc, 8, 0x31, 0, 0, true, true);
|
crc_init_ref(&crc, 8, 0x31, 0, 0, true, true);
|
||||||
for ( int i=0; i < size; ++i)
|
for ( int i=0; i < size; ++i)
|
||||||
crc_update2(&crc, buff[i], 8);
|
crc_update2(&crc, buff[i], 8);
|
||||||
return crc_finish(&crc);
|
return crc_finish(&crc);
|
||||||
}
|
}
|
||||||
// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD"
|
// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD"
|
||||||
uint32_t CRC8Mad(uint8_t *buff, size_t size) {
|
uint32_t CRC8Mad(uint8_t *buff, size_t size) {
|
||||||
crc_t crc;
|
crc_t crc;
|
||||||
crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false);
|
crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false);
|
||||||
for ( int i = 0; i < size; ++i)
|
for ( int i = 0; i < size; ++i)
|
||||||
crc_update2(&crc, buff[i], 8);
|
crc_update2(&crc, buff[i], 8);
|
||||||
return crc_finish(&crc);
|
return crc_finish(&crc);
|
||||||
}
|
}
|
||||||
// width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC"
|
// width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC"
|
||||||
uint32_t CRC4Legic(uint8_t *cmd, size_t size) {
|
uint32_t CRC4Legic(uint8_t *cmd, size_t size) {
|
||||||
crc_t crc;
|
crc_t crc;
|
||||||
crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true);
|
crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true);
|
||||||
crc_update2(&crc, 1, 1); /* CMD_READ */
|
crc_update2(&crc, 1, 1); /* CMD_READ */
|
||||||
crc_update2(&crc, cmd[0], 8);
|
crc_update2(&crc, cmd[0], 8);
|
||||||
crc_update2(&crc, cmd[1], 8);
|
crc_update2(&crc, cmd[1], 8);
|
||||||
return reflect(crc_finish(&crc), 4);
|
return reflect(crc_finish(&crc), 4);
|
||||||
}
|
}
|
||||||
// width=8 poly=0x63, reversed poly=0x8D init=0x55 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/LEGIC"
|
// width=8 poly=0x63, reversed poly=0x8D init=0x55 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/LEGIC"
|
||||||
// the CRC needs to be reversed before returned.
|
// the CRC needs to be reversed before returned.
|
||||||
uint32_t CRC8Legic(uint8_t *buff, size_t size) {
|
uint32_t CRC8Legic(uint8_t *buff, size_t size) {
|
||||||
crc_t crc;
|
crc_t crc;
|
||||||
crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true);
|
crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true);
|
||||||
for ( int i = 0; i < size; ++i)
|
for ( int i = 0; i < size; ++i)
|
||||||
crc_update2(&crc, buff[i], 8);
|
crc_update2(&crc, buff[i], 8);
|
||||||
return reflect8(crc_finish(&crc));
|
return reflect8(crc_finish(&crc));
|
||||||
}
|
}
|
40
common/crc.h
40
common/crc.h
|
@ -9,19 +9,19 @@
|
||||||
#ifndef __CRC_H
|
#ifndef __CRC_H
|
||||||
#define __CRC_H
|
#define __CRC_H
|
||||||
|
|
||||||
#include "common.h" //stdint, stddef, stdbool
|
#include "common.h" //stdint, stddef, stdbool
|
||||||
#include "util.h" // reflect, bswap_16
|
#include "util.h" // reflect, bswap_16
|
||||||
|
|
||||||
typedef struct crc {
|
typedef struct crc {
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
int order;
|
int order;
|
||||||
uint32_t polynom;
|
uint32_t polynom;
|
||||||
uint32_t initial_value;
|
uint32_t initial_value;
|
||||||
uint32_t final_xor;
|
uint32_t final_xor;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
int topbit;
|
int topbit;
|
||||||
bool refin; /* Parameter: Reflect input bytes? */
|
bool refin; /* Parameter: Reflect input bytes? */
|
||||||
bool refout; /* Parameter: Reflect output CRC? */
|
bool refout; /* Parameter: Reflect output CRC? */
|
||||||
} crc_t;
|
} crc_t;
|
||||||
|
|
||||||
/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32
|
/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32
|
||||||
|
@ -64,14 +64,14 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size);
|
||||||
|
|
||||||
/* Static initialization of a crc structure */
|
/* Static initialization of a crc structure */
|
||||||
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
|
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
|
||||||
.state = ((_initial_value) & ((1L<<(_order))-1)), \
|
.state = ((_initial_value) & ((1L<<(_order))-1)), \
|
||||||
.order = (_order), \
|
.order = (_order), \
|
||||||
.polynom = (_polynom), \
|
.polynom = (_polynom), \
|
||||||
.initial_value = (_initial_value), \
|
.initial_value = (_initial_value), \
|
||||||
.final_xor = (_final_xor), \
|
.final_xor = (_final_xor), \
|
||||||
.mask = ((1L<<(_order))-1) \
|
.mask = ((1L<<(_order))-1) \
|
||||||
.refin = false, \
|
.refin = false, \
|
||||||
.refout = false \
|
.refout = false \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __CRC_H */
|
#endif /* __CRC_H */
|
||||||
|
|
252
common/crc16.c
252
common/crc16.c
|
@ -13,125 +13,125 @@ static CrcType_t crc_type = CRC_NONE;
|
||||||
|
|
||||||
void init_table(CrcType_t ct) {
|
void init_table(CrcType_t ct) {
|
||||||
|
|
||||||
// same crc algo, and initialised already
|
// same crc algo, and initialised already
|
||||||
if ( ct == crc_type && crc_table_init)
|
if ( ct == crc_type && crc_table_init)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// not the same crc algo. reset table.
|
// not the same crc algo. reset table.
|
||||||
if ( ct != crc_type)
|
if ( ct != crc_type)
|
||||||
reset_table();
|
reset_table();
|
||||||
|
|
||||||
crc_type = ct;
|
crc_type = ct;
|
||||||
|
|
||||||
switch (ct) {
|
switch (ct) {
|
||||||
case CRC_14443_A:
|
case CRC_14443_A:
|
||||||
case CRC_14443_B:
|
case CRC_14443_B:
|
||||||
case CRC_15693:
|
case CRC_15693:
|
||||||
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
|
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
|
||||||
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
|
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
|
||||||
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
|
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
|
||||||
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
|
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
|
||||||
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
|
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
|
||||||
default:
|
default:
|
||||||
crc_table_init = false;
|
crc_table_init = false;
|
||||||
crc_type = CRC_NONE;
|
crc_type = CRC_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_table( uint16_t polynomial, bool refin) {
|
void generate_table( uint16_t polynomial, bool refin) {
|
||||||
|
|
||||||
uint16_t i, j, crc, c;
|
uint16_t i, j, crc, c;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
crc = 0;
|
crc = 0;
|
||||||
if (refin)
|
if (refin)
|
||||||
c = reflect8(i) << 8;
|
c = reflect8(i) << 8;
|
||||||
else
|
else
|
||||||
c = i << 8;
|
c = i << 8;
|
||||||
|
|
||||||
for (j = 0; j < 8; j++) {
|
for (j = 0; j < 8; j++) {
|
||||||
|
|
||||||
if ( (crc ^ c) & 0x8000 )
|
if ( (crc ^ c) & 0x8000 )
|
||||||
crc = ( crc << 1 ) ^ polynomial;
|
crc = ( crc << 1 ) ^ polynomial;
|
||||||
else
|
else
|
||||||
crc = crc << 1;
|
crc = crc << 1;
|
||||||
|
|
||||||
c = c << 1;
|
c = c << 1;
|
||||||
}
|
}
|
||||||
if (refin)
|
if (refin)
|
||||||
crc = reflect16(crc);
|
crc = reflect16(crc);
|
||||||
|
|
||||||
crc_table[i] = crc;
|
crc_table[i] = crc;
|
||||||
}
|
}
|
||||||
crc_table_init = true;
|
crc_table_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_table(void) {
|
void reset_table(void) {
|
||||||
memset(crc_table, 0, sizeof(crc_table));
|
memset(crc_table, 0, sizeof(crc_table));
|
||||||
crc_table_init = false;
|
crc_table_init = false;
|
||||||
crc_type = CRC_NONE;
|
crc_type = CRC_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// table lookup LUT solution
|
// table lookup LUT solution
|
||||||
uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout) {
|
uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout) {
|
||||||
|
|
||||||
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
|
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
|
||||||
// only usable with polynom orders of 8, 16, 24 or 32.
|
// only usable with polynom orders of 8, 16, 24 or 32.
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return (~initval);
|
return (~initval);
|
||||||
|
|
||||||
uint16_t crc = initval;
|
uint16_t crc = initval;
|
||||||
|
|
||||||
if (refin)
|
if (refin)
|
||||||
crc = reflect16(crc);
|
crc = reflect16(crc);
|
||||||
|
|
||||||
if (!refin)
|
if (!refin)
|
||||||
while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ];
|
while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ];
|
||||||
else
|
else
|
||||||
while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++];
|
while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++];
|
||||||
|
|
||||||
if (refout^refin)
|
if (refout^refin)
|
||||||
crc = reflect16(crc);
|
crc = reflect16(crc);
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bit looped solution TODO REMOVED
|
// bit looped solution TODO REMOVED
|
||||||
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
|
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
|
||||||
uint16_t i, v, tmp = 0;
|
uint16_t i, v, tmp = 0;
|
||||||
|
|
||||||
v = (crc ^ c) & 0xff;
|
v = (crc ^ c) & 0xff;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
|
|
||||||
if ( (tmp ^ v) & 1 )
|
if ( (tmp ^ v) & 1 )
|
||||||
tmp = ( tmp >> 1 ) ^ polynomial;
|
tmp = ( tmp >> 1 ) ^ polynomial;
|
||||||
else
|
else
|
||||||
tmp >>= 1;
|
tmp >>= 1;
|
||||||
|
|
||||||
v >>= 1;
|
v >>= 1;
|
||||||
}
|
}
|
||||||
return ((crc >> 8) ^ tmp) & 0xffff;
|
return ((crc >> 8) ^ tmp) & 0xffff;
|
||||||
}
|
}
|
||||||
uint16_t update_crc16( uint16_t crc, uint8_t c ) {
|
uint16_t update_crc16( uint16_t crc, uint8_t c ) {
|
||||||
return update_crc16_ex( crc, c, CRC16_POLY_CCITT);
|
return update_crc16_ex( crc, c, CRC16_POLY_CCITT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// two ways. msb or lsb loop.
|
// two ways. msb or lsb loop.
|
||||||
uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) {
|
uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) {
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return (~remainder);
|
return (~remainder);
|
||||||
|
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
c = d[i];
|
c = d[i];
|
||||||
if (refin) c = reflect8(c);
|
if (refin) c = reflect8(c);
|
||||||
|
|
||||||
// xor in at msb
|
// xor in at msb
|
||||||
remainder ^= (c << 8);
|
remainder ^= (c << 8);
|
||||||
|
|
||||||
// 8 iteration loop
|
// 8 iteration loop
|
||||||
for (uint8_t j = 8; j; --j) {
|
for (uint8_t j = 8; j; --j) {
|
||||||
if (remainder & 0x8000) {
|
if (remainder & 0x8000) {
|
||||||
remainder = (remainder << 1) ^ polynomial;
|
remainder = (remainder << 1) ^ polynomial;
|
||||||
|
@ -140,58 +140,58 @@ uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t pol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (refout)
|
if (refout)
|
||||||
remainder = reflect16(remainder);
|
remainder = reflect16(remainder);
|
||||||
|
|
||||||
return remainder;
|
return remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) {
|
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) {
|
||||||
|
|
||||||
// can't calc a crc on less than 1 byte
|
// can't calc a crc on less than 1 byte
|
||||||
if ( n == 0 ) return;
|
if ( n == 0 ) return;
|
||||||
|
|
||||||
init_table(ct);
|
init_table(ct);
|
||||||
|
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
switch (ct) {
|
switch (ct) {
|
||||||
case CRC_14443_A: crc = crc16_a(d, n); break;
|
case CRC_14443_A: crc = crc16_a(d, n); break;
|
||||||
case CRC_14443_B:
|
case CRC_14443_B:
|
||||||
case CRC_15693: crc = crc16_x25(d, n); break;
|
case CRC_15693: crc = crc16_x25(d, n); break;
|
||||||
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
|
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
|
||||||
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
|
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
|
||||||
//case CRC_LEGIC:
|
//case CRC_LEGIC:
|
||||||
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
|
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
|
||||||
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
|
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
*first = (crc & 0xFF);
|
*first = (crc & 0xFF);
|
||||||
*second = ((crc >> 8) & 0xFF);
|
*second = ((crc >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
||||||
|
|
||||||
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
||||||
if ( n < 3 ) return 0;
|
if ( n < 3 ) return 0;
|
||||||
|
|
||||||
init_table(ct);
|
init_table(ct);
|
||||||
switch (ct) {
|
switch (ct) {
|
||||||
case CRC_14443_A: return crc16_a(d, n);
|
case CRC_14443_A: return crc16_a(d, n);
|
||||||
case CRC_14443_B:
|
case CRC_14443_B:
|
||||||
case CRC_15693: return crc16_x25(d, n);
|
case CRC_15693: return crc16_x25(d, n);
|
||||||
case CRC_ICLASS: return crc16_iclass(d, n);
|
case CRC_ICLASS: return crc16_iclass(d, n);
|
||||||
case CRC_FELICA: return crc16_xmodem(d, n);
|
case CRC_FELICA: return crc16_xmodem(d, n);
|
||||||
//case CRC_LEGIC:
|
//case CRC_LEGIC:
|
||||||
case CRC_CCITT: return crc16_ccitt(d, n);
|
case CRC_CCITT: return crc16_ccitt(d, n);
|
||||||
case CRC_KERMIT: return crc16_kermit(d, n);
|
case CRC_KERMIT: return crc16_kermit(d, n);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check CRC
|
// check CRC
|
||||||
// ct crc type
|
// ct crc type
|
||||||
// d buffer with data
|
// d buffer with data
|
||||||
// n length (including crc)
|
// n length (including crc)
|
||||||
//
|
//
|
||||||
// This function uses the message + crc bytes in order to compare the "residue" afterwards.
|
// This function uses the message + crc bytes in order to compare the "residue" afterwards.
|
||||||
// crc16 algos like CRC-A become 0x000
|
// crc16 algos like CRC-A become 0x000
|
||||||
|
@ -199,39 +199,39 @@ uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
||||||
// If calculated with crc bytes, the residue should be 0xF0B8
|
// If calculated with crc bytes, the residue should be 0xF0B8
|
||||||
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
||||||
|
|
||||||
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
||||||
if ( n < 3 ) return false;
|
if ( n < 3 ) return false;
|
||||||
|
|
||||||
init_table(ct);
|
init_table(ct);
|
||||||
|
|
||||||
switch (ct) {
|
switch (ct) {
|
||||||
case CRC_14443_A: return (crc16_a(d, n) == 0);
|
case CRC_14443_A: return (crc16_a(d, n) == 0);
|
||||||
case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
||||||
case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
||||||
case CRC_ICLASS: return (crc16_iclass(d, n) == 0);
|
case CRC_ICLASS: return (crc16_iclass(d, n) == 0);
|
||||||
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
|
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
|
||||||
//case CRC_LEGIC:
|
//case CRC_LEGIC:
|
||||||
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
|
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
|
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
|
||||||
uint16_t crc16_ccitt(uint8_t const *d, size_t n) {
|
uint16_t crc16_ccitt(uint8_t const *d, size_t n) {
|
||||||
return crc16_fast(d, n, 0xffff, false, false);
|
return crc16_fast(d, n, 0xffff, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FDX-B ISO11784/85) uses KERMIT
|
// FDX-B ISO11784/85) uses KERMIT
|
||||||
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
|
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
|
||||||
uint16_t crc16_kermit(uint8_t const *d, size_t n) {
|
uint16_t crc16_kermit(uint8_t const *d, size_t n) {
|
||||||
return crc16_fast(d, n, 0x0000, true, true);
|
return crc16_fast(d, n, 0x0000, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeliCa uses XMODEM
|
// FeliCa uses XMODEM
|
||||||
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
|
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
|
||||||
uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
|
uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
|
||||||
return crc16_fast(d, n, 0x0000, false, false);
|
return crc16_fast(d, n, 0x0000, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Following standards uses X-25
|
// Following standards uses X-25
|
||||||
|
@ -240,14 +240,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
|
||||||
// ISO/IEC 13239 (formerly ISO/IEC 3309)
|
// ISO/IEC 13239 (formerly ISO/IEC 3309)
|
||||||
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
|
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
|
||||||
uint16_t crc16_x25(uint8_t const *d, size_t n) {
|
uint16_t crc16_x25(uint8_t const *d, size_t n) {
|
||||||
uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
|
uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
|
||||||
crc = ~crc;
|
crc = ~crc;
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
// CRC-A (14443-3)
|
// CRC-A (14443-3)
|
||||||
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
|
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
|
||||||
uint16_t crc16_a(uint8_t const *d, size_t n) {
|
uint16_t crc16_a(uint8_t const *d, size_t n) {
|
||||||
return crc16_fast(d, n, 0xC6C6, true, true);
|
return crc16_fast(d, n, 0xC6C6, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iClass crc
|
// iClass crc
|
||||||
|
@ -255,12 +255,12 @@ uint16_t crc16_a(uint8_t const *d, size_t n) {
|
||||||
// poly 0x1021 reflected 0x8408
|
// poly 0x1021 reflected 0x8408
|
||||||
// poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS"
|
// poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS"
|
||||||
uint16_t crc16_iclass(uint8_t const *d, size_t n) {
|
uint16_t crc16_iclass(uint8_t const *d, size_t n) {
|
||||||
return crc16_fast(d, n, 0x4807, true, true);
|
return crc16_fast(d, n, 0x4807, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This CRC-16 is used in Legic Advant systems.
|
// This CRC-16 is used in Legic Advant systems.
|
||||||
// poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
|
// poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
|
||||||
uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
|
uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
|
||||||
uint16_t initial = uidcrc << 8 | uidcrc;
|
uint16_t initial = uidcrc << 8 | uidcrc;
|
||||||
return crc16_fast(d, n, initial, true, true);
|
return crc16_fast(d, n, initial, true, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,20 @@
|
||||||
|
|
||||||
#define CRC16_POLY_CCITT 0x1021
|
#define CRC16_POLY_CCITT 0x1021
|
||||||
#define CRC16_POLY_LEGIC 0xc6c6 //0x6363
|
#define CRC16_POLY_LEGIC 0xc6c6 //0x6363
|
||||||
#define CRC16_POLY_DNP 0x3d65
|
#define CRC16_POLY_DNP 0x3d65
|
||||||
|
|
||||||
#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
|
#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CRC_NONE,
|
CRC_NONE,
|
||||||
CRC_14443_A,
|
CRC_14443_A,
|
||||||
CRC_14443_B,
|
CRC_14443_B,
|
||||||
CRC_15693,
|
CRC_15693,
|
||||||
CRC_ICLASS,
|
CRC_ICLASS,
|
||||||
CRC_FELICA,
|
CRC_FELICA,
|
||||||
CRC_LEGIC,
|
CRC_LEGIC,
|
||||||
CRC_CCITT,
|
CRC_CCITT,
|
||||||
CRC_KERMIT,
|
CRC_KERMIT,
|
||||||
} CrcType_t;
|
} CrcType_t;
|
||||||
|
|
||||||
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );
|
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#define CRC64_ECMA_PRESET 0x0000000000000000
|
#define CRC64_ECMA_PRESET 0x0000000000000000
|
||||||
|
|
||||||
const uint64_t crc64_table[] = {
|
const uint64_t crc64_table[] = {
|
||||||
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
|
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
|
||||||
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
|
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
|
||||||
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
|
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
|
||||||
0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
|
0xDB55AACF12C73561, 0x99A54B24BB2D03F2, 0x5EB4691841135847, 0x1C4488F3E8F96ED4,
|
||||||
|
@ -74,10 +74,10 @@ const uint64_t crc64_table[] = {
|
||||||
|
|
||||||
void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) {
|
void crc64 (const uint8_t *data, const size_t len, uint64_t *crc) {
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
|
uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
|
||||||
*crc = crc64_table[tableIndex] ^ (*crc << 8);
|
*crc = crc64_table[tableIndex] ^ (*crc << 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//suint8_t x = (c & 0xFF00000000000000 ) >> 56;
|
//suint8_t x = (c & 0xFF00000000000000 ) >> 56;
|
|
@ -1,9 +1,9 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
/* This is the default version.c file that Makefile.common falls back to if perl is not available */
|
/* This is the default version.c file that Makefile.common falls back to if perl is not available */
|
||||||
const struct version_information __attribute__((section(".version_information"))) version_information = {
|
const struct version_information __attribute__((section(".version_information"))) version_information = {
|
||||||
VERSION_INFORMATION_MAGIC,
|
VERSION_INFORMATION_MAGIC,
|
||||||
1, /* version 1 */
|
1, /* version 1 */
|
||||||
0, /* version information not present */
|
0, /* version information not present */
|
||||||
2, /* cleanliness couldn't be determined */
|
2, /* cleanliness couldn't be determined */
|
||||||
/* Remaining fields: zero */
|
/* Remaining fields: zero */
|
||||||
};
|
};
|
||||||
|
|
132
common/desfire.h
132
common/desfire.h
|
@ -55,15 +55,15 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
enum DESFIRE_AUTH_SCHEME {
|
enum DESFIRE_AUTH_SCHEME {
|
||||||
AS_LEGACY,
|
AS_LEGACY,
|
||||||
AS_NEW
|
AS_NEW
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DESFIRE_CRYPTOALGO {
|
enum DESFIRE_CRYPTOALGO {
|
||||||
T_DES = 0x00,
|
T_DES = 0x00,
|
||||||
T_3DES = 0x01,
|
T_3DES = 0x01,
|
||||||
T_3K3DES = 0x02,
|
T_3K3DES = 0x02,
|
||||||
T_AES = 0x03
|
T_AES = 0x03
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ struct desfire_key {
|
||||||
// DES_key_schedule ks1;
|
// DES_key_schedule ks1;
|
||||||
// DES_key_schedule ks2;
|
// DES_key_schedule ks2;
|
||||||
// DES_key_schedule ks3;
|
// DES_key_schedule ks3;
|
||||||
AesCtx aes_ks;
|
AesCtx aes_ks;
|
||||||
uint8_t cmac_sk1[24];
|
uint8_t cmac_sk1[24];
|
||||||
uint8_t cmac_sk2[24];
|
uint8_t cmac_sk2[24];
|
||||||
uint8_t aes_version;
|
uint8_t aes_version;
|
||||||
|
@ -89,10 +89,10 @@ struct desfire_tag {
|
||||||
uint8_t last_internal_error;
|
uint8_t last_internal_error;
|
||||||
uint8_t last_pcd_error;
|
uint8_t last_pcd_error;
|
||||||
desfirekey_t session_key;
|
desfirekey_t session_key;
|
||||||
enum DESFIRE_AUTH_SCHEME authentication_scheme;
|
enum DESFIRE_AUTH_SCHEME authentication_scheme;
|
||||||
uint8_t authenticated_key_no;
|
uint8_t authenticated_key_no;
|
||||||
|
|
||||||
uint8_t ivect[MAX_CRYPTO_BLOCK_SIZE];
|
uint8_t ivect[MAX_CRYPTO_BLOCK_SIZE];
|
||||||
uint8_t cmac[16];
|
uint8_t cmac[16];
|
||||||
uint8_t *crypto_buffer;
|
uint8_t *crypto_buffer;
|
||||||
size_t crypto_buffer_size;
|
size_t crypto_buffer_size;
|
||||||
|
@ -111,66 +111,66 @@ enum DESFIRE_FILE_TYPES {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DESFIRE_STATUS {
|
enum DESFIRE_STATUS {
|
||||||
OPERATION_OK = 0x00,
|
OPERATION_OK = 0x00,
|
||||||
NO_CHANGES = 0x0c,
|
NO_CHANGES = 0x0c,
|
||||||
OUT_OF_EEPROM_ERROR = 0x0e,
|
OUT_OF_EEPROM_ERROR = 0x0e,
|
||||||
ILLEGAL_COMMAND_CODE = 0x1c,
|
ILLEGAL_COMMAND_CODE = 0x1c,
|
||||||
INTEGRITY_ERROR = 0x1e,
|
INTEGRITY_ERROR = 0x1e,
|
||||||
NO_SUCH_KEY = 0x40,
|
NO_SUCH_KEY = 0x40,
|
||||||
LENGTH_ERROR = 0x7e,
|
LENGTH_ERROR = 0x7e,
|
||||||
PERMISSION_DENIED = 0x9d,
|
PERMISSION_DENIED = 0x9d,
|
||||||
PARAMETER_ERROR = 0x9e,
|
PARAMETER_ERROR = 0x9e,
|
||||||
APPLICATION_NOT_FOUND = 0xa0,
|
APPLICATION_NOT_FOUND = 0xa0,
|
||||||
APPL_INTEGRITY_ERROR = 0xa1,
|
APPL_INTEGRITY_ERROR = 0xa1,
|
||||||
AUTHENTICATION_ERROR = 0xae,
|
AUTHENTICATION_ERROR = 0xae,
|
||||||
ADDITIONAL_FRAME = 0xaf,
|
ADDITIONAL_FRAME = 0xaf,
|
||||||
BOUNDARY_ERROR = 0xbe,
|
BOUNDARY_ERROR = 0xbe,
|
||||||
PICC_INTEGRITY_ERROR = 0xc1,
|
PICC_INTEGRITY_ERROR = 0xc1,
|
||||||
COMMAND_ABORTED = 0xca,
|
COMMAND_ABORTED = 0xca,
|
||||||
PICC_DISABLED_ERROR = 0xcd,
|
PICC_DISABLED_ERROR = 0xcd,
|
||||||
COUNT_ERROR = 0xce,
|
COUNT_ERROR = 0xce,
|
||||||
DUPLICATE_ERROR = 0xde,
|
DUPLICATE_ERROR = 0xde,
|
||||||
EEPROM_ERROR = 0xee,
|
EEPROM_ERROR = 0xee,
|
||||||
FILE_NOT_FOUND = 0xf0,
|
FILE_NOT_FOUND = 0xf0,
|
||||||
FILE_INTEGRITY_ERROR = 0xf1
|
FILE_INTEGRITY_ERROR = 0xf1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DESFIRE_CMD {
|
enum DESFIRE_CMD {
|
||||||
CREATE_APPLICATION = 0xca,
|
CREATE_APPLICATION = 0xca,
|
||||||
DELETE_APPLICATION = 0xda,
|
DELETE_APPLICATION = 0xda,
|
||||||
GET_APPLICATION_IDS = 0x6a,
|
GET_APPLICATION_IDS = 0x6a,
|
||||||
SELECT_APPLICATION = 0x5a,
|
SELECT_APPLICATION = 0x5a,
|
||||||
FORMAT_PICC = 0xfc,
|
FORMAT_PICC = 0xfc,
|
||||||
GET_VERSION = 0x60,
|
GET_VERSION = 0x60,
|
||||||
READ_DATA = 0xbd,
|
READ_DATA = 0xbd,
|
||||||
WRITE_DATA = 0x3d,
|
WRITE_DATA = 0x3d,
|
||||||
GET_VALUE = 0x6c,
|
GET_VALUE = 0x6c,
|
||||||
CREDIT = 0x0c,
|
CREDIT = 0x0c,
|
||||||
DEBIT = 0xdc,
|
DEBIT = 0xdc,
|
||||||
LIMITED_CREDIT = 0x1c,
|
LIMITED_CREDIT = 0x1c,
|
||||||
WRITE_RECORD = 0x3b,
|
WRITE_RECORD = 0x3b,
|
||||||
READ_RECORDS = 0xbb,
|
READ_RECORDS = 0xbb,
|
||||||
CLEAR_RECORD_FILE = 0xeb,
|
CLEAR_RECORD_FILE = 0xeb,
|
||||||
COMMIT_TRANSACTION = 0xc7,
|
COMMIT_TRANSACTION = 0xc7,
|
||||||
ABORT_TRANSACTION = 0xa7,
|
ABORT_TRANSACTION = 0xa7,
|
||||||
GET_FREE_MEMORY = 0x6e,
|
GET_FREE_MEMORY = 0x6e,
|
||||||
GET_FILE_IDS = 0x6f,
|
GET_FILE_IDS = 0x6f,
|
||||||
GET_FILE_SETTINGS = 0xf5,
|
GET_FILE_SETTINGS = 0xf5,
|
||||||
CHANGE_FILE_SETTINGS = 0x5f,
|
CHANGE_FILE_SETTINGS = 0x5f,
|
||||||
CREATE_STD_DATA_FILE = 0xcd,
|
CREATE_STD_DATA_FILE = 0xcd,
|
||||||
CREATE_BACKUP_DATA_FILE = 0xcb,
|
CREATE_BACKUP_DATA_FILE = 0xcb,
|
||||||
CREATE_VALUE_FILE = 0xcc,
|
CREATE_VALUE_FILE = 0xcc,
|
||||||
CREATE_LINEAR_RECORD_FILE = 0xc1,
|
CREATE_LINEAR_RECORD_FILE = 0xc1,
|
||||||
CREATE_CYCLIC_RECORD_FILE = 0xc0,
|
CREATE_CYCLIC_RECORD_FILE = 0xc0,
|
||||||
DELETE_FILE = 0xdf,
|
DELETE_FILE = 0xdf,
|
||||||
AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE
|
AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE
|
||||||
AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD
|
AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD
|
||||||
AUTHENTICATE_AES = 0xaa,
|
AUTHENTICATE_AES = 0xaa,
|
||||||
CHANGE_KEY_SETTINGS = 0x54,
|
CHANGE_KEY_SETTINGS = 0x54,
|
||||||
GET_KEY_SETTINGS = 0x45,
|
GET_KEY_SETTINGS = 0x45,
|
||||||
CHANGE_KEY = 0xc4,
|
CHANGE_KEY = 0xc4,
|
||||||
GET_KEY_VERSION = 0x64,
|
GET_KEY_VERSION = 0x64,
|
||||||
AUTHENTICATION_FRAME = 0xAF
|
AUTHENTICATION_FRAME = 0xAF
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1056
common/i2c.c
1056
common/i2c.c
File diff suppressed because it is too large
Load diff
18
common/i2c.h
18
common/i2c.h
|
@ -8,16 +8,16 @@
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
|
|
||||||
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
|
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
|
||||||
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
|
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
|
||||||
|
|
||||||
#define I2C_DEVICE_CMD_GENERATE_ATR 0x01
|
#define I2C_DEVICE_CMD_GENERATE_ATR 0x01
|
||||||
#define I2C_DEVICE_CMD_SEND 0x02
|
#define I2C_DEVICE_CMD_SEND 0x02
|
||||||
#define I2C_DEVICE_CMD_READ 0x03
|
#define I2C_DEVICE_CMD_READ 0x03
|
||||||
#define I2C_DEVICE_CMD_SETBAUD 0x04
|
#define I2C_DEVICE_CMD_SETBAUD 0x04
|
||||||
#define I2C_DEVICE_CMD_SIM_CLC 0x05
|
#define I2C_DEVICE_CMD_SIM_CLC 0x05
|
||||||
#define I2C_DEVICE_CMD_GETVERSION 0x06
|
#define I2C_DEVICE_CMD_GETVERSION 0x06
|
||||||
#define I2C_DEVICE_CMD_SEND_T0 0x07
|
#define I2C_DEVICE_CMD_SEND_T0 0x07
|
||||||
|
|
||||||
|
|
||||||
void I2C_recovery(void);
|
void I2C_recovery(void);
|
||||||
|
|
|
@ -22,7 +22,7 @@ void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint16_t crc = CrcType;
|
uint16_t crc = CrcType;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
b = *data++;
|
b = *data++;
|
||||||
UpdateCrc14443(b, &crc);
|
UpdateCrc14443(b, &crc);
|
||||||
} while (--length);
|
} while (--length);
|
||||||
|
@ -36,10 +36,10 @@ void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) {
|
bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) {
|
||||||
if (length < 3) return false;
|
if (length < 3) return false;
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
ComputeCrc14443(CrcType, data, length - 2, &b1, &b2);
|
ComputeCrc14443(CrcType, data, length - 2, &b1, &b2);
|
||||||
if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
|
if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,17 @@
|
||||||
|
|
||||||
// returns a string representation of the UID
|
// returns a string representation of the UID
|
||||||
// UID is transmitted and stored LSB first, displayed MSB first
|
// UID is transmitted and stored LSB first, displayed MSB first
|
||||||
// target char* buffer, where to put the UID, if NULL a static buffer is returned
|
// target char* buffer, where to put the UID, if NULL a static buffer is returned
|
||||||
// uid[] the UID in transmission order
|
// uid[] the UID in transmission order
|
||||||
// return: ptr to string
|
// return: ptr to string
|
||||||
char* Iso15693sprintUID(char *target, uint8_t *uid) {
|
char* Iso15693sprintUID(char *target, uint8_t *uid) {
|
||||||
|
|
||||||
static char tempbuf[2*8+1] = {0};
|
static char tempbuf[2*8+1] = {0};
|
||||||
if (target == NULL)
|
if (target == NULL)
|
||||||
target = tempbuf;
|
target = tempbuf;
|
||||||
sprintf(target, "%02X %02X %02X %02X %02X %02X %02X %02X",
|
sprintf(target, "%02X %02X %02X %02X %02X %02X %02X %02X",
|
||||||
uid[7], uid[6], uid[5], uid[4],
|
uid[7], uid[6], uid[5], uid[4],
|
||||||
uid[3], uid[2], uid[1], uid[0]
|
uid[3], uid[2], uid[1], uid[0]
|
||||||
);
|
);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
|
@ -17,58 +17,58 @@
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
|
|
||||||
// REQUEST FLAGS
|
// REQUEST FLAGS
|
||||||
#define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
#define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
||||||
#define ISO15_REQ_SUBCARRIER_TWO 0x01 // Tag should respond using two subcarriers (FSK)
|
#define ISO15_REQ_SUBCARRIER_TWO 0x01 // Tag should respond using two subcarriers (FSK)
|
||||||
#define ISO15_REQ_DATARATE_LOW 0x00 // Tag should respond using low data rate
|
#define ISO15_REQ_DATARATE_LOW 0x00 // Tag should respond using low data rate
|
||||||
#define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
|
#define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
|
||||||
#define ISO15_REQ_NONINVENTORY 0x00
|
#define ISO15_REQ_NONINVENTORY 0x00
|
||||||
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
|
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
|
||||||
#define ISO15_REQ_PROTOCOL_NONEXT 0x00
|
#define ISO15_REQ_PROTOCOL_NONEXT 0x00
|
||||||
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
|
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
|
||||||
|
|
||||||
// REQUEST FLAGS when INVENTORY is not set
|
// REQUEST FLAGS when INVENTORY is not set
|
||||||
#define ISO15_REQ_SELECT 0x10 // only selected cards response
|
#define ISO15_REQ_SELECT 0x10 // only selected cards response
|
||||||
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address
|
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address
|
||||||
#define ISO15_REQ_OPTION 0x40 // Command specific option selector
|
#define ISO15_REQ_OPTION 0x40 // Command specific option selector
|
||||||
|
|
||||||
//REQUEST FLAGS when INVENTORY is set
|
//REQUEST FLAGS when INVENTORY is set
|
||||||
#define ISO15_REQINV_AFI 0x10 // AFI Field is present
|
#define ISO15_REQINV_AFI 0x10 // AFI Field is present
|
||||||
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot
|
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot
|
||||||
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots
|
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots
|
||||||
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector
|
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector
|
||||||
|
|
||||||
//RESPONSE FLAGS
|
//RESPONSE FLAGS
|
||||||
#define ISO15_RES_ERROR 0x01
|
#define ISO15_RES_ERROR 0x01
|
||||||
#define ISO15_RES_EXT 0x08 // Protocol Extention
|
#define ISO15_RES_EXT 0x08 // Protocol Extention
|
||||||
|
|
||||||
// RESPONSE ERROR CODES
|
// RESPONSE ERROR CODES
|
||||||
#define ISO15_NOERROR 0x00
|
#define ISO15_NOERROR 0x00
|
||||||
#define ISO15_ERROR_CMD_NOT_SUP 0x01 // Command not supported
|
#define ISO15_ERROR_CMD_NOT_SUP 0x01 // Command not supported
|
||||||
#define ISO15_ERROR_CMD_NOT_REC 0x02 // Command not recognized (eg. parameter error)
|
#define ISO15_ERROR_CMD_NOT_REC 0x02 // Command not recognized (eg. parameter error)
|
||||||
#define ISO15_ERROR_CMD_OPTION 0x03 // Command option not supported
|
#define ISO15_ERROR_CMD_OPTION 0x03 // Command option not supported
|
||||||
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
|
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
|
||||||
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
|
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
|
||||||
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
|
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
|
||||||
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
|
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
|
||||||
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
|
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
|
||||||
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
|
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
|
||||||
|
|
||||||
// COMMAND CODES
|
// COMMAND CODES
|
||||||
#define ISO15_CMD_INVENTORY 0x01
|
#define ISO15_CMD_INVENTORY 0x01
|
||||||
#define ISO15_CMD_STAYQUIET 0x02
|
#define ISO15_CMD_STAYQUIET 0x02
|
||||||
#define ISO15_CMD_READ 0x20
|
#define ISO15_CMD_READ 0x20
|
||||||
#define ISO15_CMD_WRITE 0x21
|
#define ISO15_CMD_WRITE 0x21
|
||||||
#define ISO15_CMD_LOCK 0x22
|
#define ISO15_CMD_LOCK 0x22
|
||||||
#define ISO15_CMD_READMULTI 0x23
|
#define ISO15_CMD_READMULTI 0x23
|
||||||
#define ISO15_CMD_WRITEMULTI 0x24
|
#define ISO15_CMD_WRITEMULTI 0x24
|
||||||
#define ISO15_CMD_SELECT 0x25
|
#define ISO15_CMD_SELECT 0x25
|
||||||
#define ISO15_CMD_RESET 0x26
|
#define ISO15_CMD_RESET 0x26
|
||||||
#define ISO15_CMD_WRITEAFI 0x27
|
#define ISO15_CMD_WRITEAFI 0x27
|
||||||
#define ISO15_CMD_LOCKAFI 0x28
|
#define ISO15_CMD_LOCKAFI 0x28
|
||||||
#define ISO15_CMD_WRITEDSFID 0x29
|
#define ISO15_CMD_WRITEDSFID 0x29
|
||||||
#define ISO15_CMD_LOCKDSFID 0x2A
|
#define ISO15_CMD_LOCKDSFID 0x2A
|
||||||
#define ISO15_CMD_SYSINFO 0x2B
|
#define ISO15_CMD_SYSINFO 0x2B
|
||||||
#define ISO15_CMD_SECSTATUS 0x2C
|
#define ISO15_CMD_SECSTATUS 0x2C
|
||||||
|
|
||||||
char* Iso15693sprintUID(char *target, uint8_t *uid);
|
char* Iso15693sprintUID(char *target, uint8_t *uid);
|
||||||
|
|
||||||
|
@ -78,49 +78,49 @@ char* Iso15693sprintUID(char *target, uint8_t *uid);
|
||||||
// Mode: highspeed && one subcarrier (ASK)
|
// Mode: highspeed && one subcarrier (ASK)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
|
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
|
||||||
|
|
||||||
// SOF defined as
|
// SOF defined as
|
||||||
// 1) Unmodulated time of 56.64us
|
// 1) Unmodulated time of 56.64us
|
||||||
// 2) 24 pulses of 423.75khz
|
// 2) 24 pulses of 423.75khz
|
||||||
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
||||||
|
|
||||||
static const int Iso15693FrameSOF[] = {
|
static const int Iso15693FrameSOF[] = {
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
1, 1, 1, 1
|
1, 1, 1, 1
|
||||||
};
|
};
|
||||||
static const int Iso15693Logic0[] = {
|
static const int Iso15693Logic0[] = {
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
-1, -1, -1, -1
|
-1, -1, -1, -1
|
||||||
};
|
};
|
||||||
static const int Iso15693Logic1[] = {
|
static const int Iso15693Logic1[] = {
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
1, 1, 1, 1
|
1, 1, 1, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// EOF defined as
|
// EOF defined as
|
||||||
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
||||||
// 2) 24 pulses of 423.75khz
|
// 2) 24 pulses of 423.75khz
|
||||||
// 3) Unmodulated time of 56.64us
|
// 3) Unmodulated time of 56.64us
|
||||||
static const int Iso15693FrameEOF[] = {
|
static const int Iso15693FrameEOF[] = {
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
1, 1, 1, 1,
|
1, 1, 1, 1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
-1, -1, -1, -1,
|
-1, -1, -1, -1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -11,13 +11,13 @@ ms of the GNU GPL, version 2 or,
|
||||||
|
|
||||||
/* AT91SAM7S256 has 256k Flash and 64k RAM */
|
/* AT91SAM7S256 has 256k Flash and 64k RAM */
|
||||||
/* AT91SAM7S512 has 512k Flash and 64k RAM */
|
/* AT91SAM7S512 has 512k Flash and 64k RAM */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */
|
bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */
|
||||||
bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */
|
bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */
|
||||||
osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */
|
osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */
|
||||||
ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */
|
ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */
|
||||||
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
|
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Export some information that can be used from within the firmware */
|
/* Export some information that can be used from within the firmware */
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
// c keeps track on which step the prng is.
|
// c keeps track on which step the prng is.
|
||||||
// legic_prng_get_bit() = gets a bit muxed from a and b.
|
// legic_prng_get_bit() = gets a bit muxed from a and b.
|
||||||
struct lfsr {
|
struct lfsr {
|
||||||
uint8_t a;
|
uint8_t a;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
} lfsr;
|
} lfsr;
|
||||||
|
|
||||||
// Normal init is set following variables with a random value IV
|
// Normal init is set following variables with a random value IV
|
||||||
|
@ -28,38 +28,38 @@ struct lfsr {
|
||||||
// which is used in the initialisation phase sending the IV
|
// which is used in the initialisation phase sending the IV
|
||||||
//
|
//
|
||||||
void legic_prng_init(uint8_t iv) {
|
void legic_prng_init(uint8_t iv) {
|
||||||
lfsr.a = iv;
|
lfsr.a = iv;
|
||||||
lfsr.b = 0; // hack to get a always 0 keystream
|
lfsr.b = 0; // hack to get a always 0 keystream
|
||||||
lfsr.c = 0;
|
lfsr.c = 0;
|
||||||
if(iv)
|
if(iv)
|
||||||
lfsr.b = (iv << 1) | 1;
|
lfsr.b = (iv << 1) | 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void legic_prng_forward(int count) {
|
void legic_prng_forward(int count) {
|
||||||
if (count == 0) return;
|
if (count == 0) return;
|
||||||
|
|
||||||
lfsr.c += count;
|
lfsr.c += count;
|
||||||
while(count--) {
|
while(count--) {
|
||||||
// According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
|
// According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
|
||||||
lfsr.a = (lfsr.a >> 1 | (lfsr.a ^ lfsr.a >> 6) << 6) & 0x7F;
|
lfsr.a = (lfsr.a >> 1 | (lfsr.a ^ lfsr.a >> 6) << 6) & 0x7F;
|
||||||
lfsr.b = lfsr.b >> 1 | (lfsr.b ^ lfsr.b >> 2 ^ lfsr.b >> 3 ^ lfsr.b >> 7) << 7;
|
lfsr.b = lfsr.b >> 1 | (lfsr.b ^ lfsr.b >> 2 ^ lfsr.b >> 3 ^ lfsr.b >> 7) << 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t legic_prng_count() {
|
uint32_t legic_prng_count() {
|
||||||
return lfsr.c;
|
return lfsr.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t legic_prng_get_bit() {
|
uint8_t legic_prng_get_bit() {
|
||||||
uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) );
|
uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) );
|
||||||
return lfsr.b >> idx & 1;
|
return lfsr.b >> idx & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t legic_prng_get_bits(uint8_t len){
|
uint32_t legic_prng_get_bits(uint8_t len){
|
||||||
uint32_t a = 0;
|
uint32_t a = 0;
|
||||||
for(uint8_t i = 0; i < len; ++i) {
|
for(uint8_t i = 0; i < len; ++i) {
|
||||||
a |= legic_prng_get_bit() << i;
|
a |= legic_prng_get_bit() << i;
|
||||||
legic_prng_forward(1);
|
legic_prng_forward(1);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
3072
common/lfdemod.c
3072
common/lfdemod.c
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@
|
||||||
#include <stdlib.h> // for
|
#include <stdlib.h> // for
|
||||||
#include <stdbool.h> // for bool
|
#include <stdbool.h> // for bool
|
||||||
#include "parity.h" // for parity test
|
#include "parity.h" // for parity test
|
||||||
#include "util.h" // for ARRAYLEN
|
#include "util.h" // for ARRAYLEN
|
||||||
|
|
||||||
//might not be high enough for noisy environments
|
//might not be high enough for noisy environments
|
||||||
#define NOISE_AMPLITUDE_THRESHOLD 10
|
#define NOISE_AMPLITUDE_THRESHOLD 10
|
||||||
|
@ -30,11 +30,11 @@
|
||||||
|
|
||||||
//generic
|
//generic
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int low;
|
int low;
|
||||||
int high;
|
int high;
|
||||||
int mean;
|
int mean;
|
||||||
int amplitude;
|
int amplitude;
|
||||||
bool isnoise;
|
bool isnoise;
|
||||||
} signal_t;
|
} signal_t;
|
||||||
signal_t* getSignalProperties(void);
|
signal_t* getSignalProperties(void);
|
||||||
|
|
||||||
|
@ -50,12 +50,12 @@ extern int askdemod(uint8_t *bits, size_t *size, int *clk, int *invert, int
|
||||||
extern int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx);
|
extern int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx);
|
||||||
extern void askAmp(uint8_t *bits, size_t size);
|
extern void askAmp(uint8_t *bits, size_t size);
|
||||||
extern int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert);
|
extern int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert);
|
||||||
extern uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest);
|
extern uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest);
|
||||||
extern uint32_t bytebits_to_byte(uint8_t *src, size_t numbits);
|
extern uint32_t bytebits_to_byte(uint8_t *src, size_t numbits);
|
||||||
extern uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits);
|
extern uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits);
|
||||||
extern uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj);
|
extern uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj);
|
||||||
extern int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr);
|
extern int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr);
|
||||||
extern bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low);
|
extern bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low);
|
||||||
extern uint8_t detectFSKClk(uint8_t *bits, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge);
|
extern uint8_t detectFSKClk(uint8_t *bits, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge);
|
||||||
extern int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx);
|
extern int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx);
|
||||||
extern int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc);
|
extern int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc);
|
||||||
|
@ -69,8 +69,8 @@ extern int ManchesterEncode(uint8_t *bits, size_t size);
|
||||||
extern int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
extern int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
|
||||||
extern int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
extern int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
||||||
extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||||
extern bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
extern bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||||
extern bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone);
|
extern bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone);
|
||||||
extern int pskRawDemod(uint8_t *dest, size_t *size, int *clock, int *invert);
|
extern int pskRawDemod(uint8_t *dest, size_t *size, int *clock, int *invert);
|
||||||
extern int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *startIdx);
|
extern int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *startIdx);
|
||||||
extern void psk2TOpsk1(uint8_t *bits, size_t size);
|
extern void psk2TOpsk1(uint8_t *bits, size_t size);
|
||||||
|
|
|
@ -22,23 +22,23 @@ extern const uint8_t OddByteParity[256];
|
||||||
|
|
||||||
|
|
||||||
static inline bool oddparity8(const uint8_t x) {
|
static inline bool oddparity8(const uint8_t x) {
|
||||||
return OddByteParity[x];
|
return OddByteParity[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool evenparity8(const uint8_t x) {
|
static inline bool evenparity8(const uint8_t x) {
|
||||||
return !OddByteParity[x];
|
return !OddByteParity[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool evenparity32(uint32_t x)
|
static inline bool evenparity32(uint32_t x)
|
||||||
{
|
{
|
||||||
#if !defined __GNUC__
|
#if !defined __GNUC__
|
||||||
x ^= x >> 16;
|
x ^= x >> 16;
|
||||||
x ^= x >> 8;
|
x ^= x >> 8;
|
||||||
return evenparity8(x);
|
return evenparity8(x);
|
||||||
#else
|
#else
|
||||||
return __builtin_parity(x);
|
return __builtin_parity(x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ static inline bool evenparity32(uint32_t x)
|
||||||
static inline bool oddparity32(uint32_t x)
|
static inline bool oddparity32(uint32_t x)
|
||||||
{
|
{
|
||||||
#if !defined __GNUC__
|
#if !defined __GNUC__
|
||||||
x ^= x >> 16;
|
x ^= x >> 16;
|
||||||
x ^= x >> 8;
|
x ^= x >> 8;
|
||||||
return oddparity8(x);
|
return oddparity8(x);
|
||||||
#else
|
#else
|
||||||
return !__builtin_parity(x);
|
return !__builtin_parity(x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ uint32_t burtle_get_mod( prng_ctx *x ) {
|
||||||
|
|
||||||
void burtle_init_mod(prng_ctx *x, uint32_t seed ) {
|
void burtle_init_mod(prng_ctx *x, uint32_t seed ) {
|
||||||
x->a = 0xf1ea5eed;
|
x->a = 0xf1ea5eed;
|
||||||
x->b = x->c = x->d = seed;
|
x->b = x->c = x->d = seed;
|
||||||
for (uint8_t i=0; i < 42; ++i) {
|
for (uint8_t i=0; i < 42; ++i) {
|
||||||
(void)burtle_get_mod(x);
|
(void)burtle_get_mod(x);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ void burtle_init(prng_ctx *x, uint32_t seed ) {
|
||||||
|
|
||||||
|
|
||||||
uint32_t GetSimplePrng( uint32_t seed ){
|
uint32_t GetSimplePrng( uint32_t seed ){
|
||||||
seed *= 0x19660D;
|
seed *= 0x19660D;
|
||||||
seed += 0x3C6EF35F;
|
seed += 0x3C6EF35F;
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
typedef struct prng_ctx {
|
typedef struct prng_ctx {
|
||||||
uint32_t a;
|
uint32_t a;
|
||||||
uint32_t b;
|
uint32_t b;
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
uint32_t d;
|
uint32_t d;
|
||||||
} prng_ctx;
|
} prng_ctx;
|
||||||
|
|
||||||
//uint32_t burtle_get( prng_ctx *x );
|
//uint32_t burtle_get( prng_ctx *x );
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
// ATA55xx shared presets & routines
|
// ATA55xx shared presets & routines
|
||||||
uint32_t GetT55xxClockBit(uint32_t clock) {
|
uint32_t GetT55xxClockBit(uint32_t clock) {
|
||||||
switch (clock) {
|
switch (clock) {
|
||||||
case 128: return T55x7_BITRATE_RF_128;
|
case 128: return T55x7_BITRATE_RF_128;
|
||||||
case 100: return T55x7_BITRATE_RF_100;
|
case 100: return T55x7_BITRATE_RF_100;
|
||||||
case 64: return T55x7_BITRATE_RF_64;
|
case 64: return T55x7_BITRATE_RF_64;
|
||||||
case 50: return T55x7_BITRATE_RF_50;
|
case 50: return T55x7_BITRATE_RF_50;
|
||||||
case 40: return T55x7_BITRATE_RF_40;
|
case 40: return T55x7_BITRATE_RF_40;
|
||||||
case 32: return T55x7_BITRATE_RF_32;
|
case 32: return T55x7_BITRATE_RF_32;
|
||||||
case 16: return T55x7_BITRATE_RF_16;
|
case 16: return T55x7_BITRATE_RF_16;
|
||||||
case 8: return T55x7_BITRATE_RF_8;
|
case 8: return T55x7_BITRATE_RF_8;
|
||||||
default : return 0;
|
default : return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
|
@ -20,122 +20,122 @@ uint32_t GetT55xxClockBit(uint32_t clock) {
|
||||||
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
||||||
|
|
||||||
uint8_t isset(uint8_t val, uint8_t mask) {
|
uint8_t isset(uint8_t val, uint8_t mask) {
|
||||||
return (val & mask);
|
return (val & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t notset(uint8_t val, uint8_t mask){
|
uint8_t notset(uint8_t val, uint8_t mask){
|
||||||
return !(val & mask);
|
return !(val & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_config(const picopass_hdr *hdr) {
|
void fuse_config(const picopass_hdr *hdr) {
|
||||||
uint8_t fuses = hdr->conf.fuses;
|
uint8_t fuses = hdr->conf.fuses;
|
||||||
|
|
||||||
if (isset(fuses,FUSE_FPERS))
|
if (isset(fuses,FUSE_FPERS))
|
||||||
PrintAndLogDevice(SUCCESS, "\tMode: Personalization [Programmable]");
|
PrintAndLogDevice(SUCCESS, "\tMode: Personalization [Programmable]");
|
||||||
else
|
else
|
||||||
PrintAndLogDevice(NORMAL, "\tMode: Application [Locked]");
|
PrintAndLogDevice(NORMAL, "\tMode: Application [Locked]");
|
||||||
|
|
||||||
if (isset(fuses, FUSE_CODING1)) {
|
if (isset(fuses, FUSE_CODING1)) {
|
||||||
PrintAndLogDevice(NORMAL, "\tCoding: RFU");
|
PrintAndLogDevice(NORMAL, "\tCoding: RFU");
|
||||||
} else {
|
} else {
|
||||||
if( isset( fuses , FUSE_CODING0))
|
if( isset( fuses , FUSE_CODING0))
|
||||||
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693");
|
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693");
|
||||||
else
|
else
|
||||||
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443B only");
|
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443B only");
|
||||||
}
|
}
|
||||||
// 1 1
|
// 1 1
|
||||||
if( isset (fuses,FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Secured page, keys not locked");
|
if( isset (fuses,FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Secured page, keys not locked");
|
||||||
// 1 0
|
// 1 0
|
||||||
if( isset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: Secured page, keys locked");
|
if( isset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: Secured page, keys locked");
|
||||||
// 0 1
|
// 0 1
|
||||||
if( notset (fuses,FUSE_CRYPT1) && isset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Non secured page");
|
if( notset (fuses,FUSE_CRYPT1) && isset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Non secured page");
|
||||||
// 0 0
|
// 0 0
|
||||||
if( notset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: No auth possible. Read only if RA is enabled");
|
if( notset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: No auth possible. Read only if RA is enabled");
|
||||||
|
|
||||||
if( isset( fuses, FUSE_RA))
|
if( isset( fuses, FUSE_RA))
|
||||||
PrintAndLogDevice(NORMAL, "\tRA: Read access enabled");
|
PrintAndLogDevice(NORMAL, "\tRA: Read access enabled");
|
||||||
else
|
else
|
||||||
PrintAndLogDevice(WARNING, "\tRA: Read access not enabled");
|
PrintAndLogDevice(WARNING, "\tRA: Read access not enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) {
|
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) {
|
||||||
// mem-bit 5, mem-bit 7, chip-bit 4: defines chip type
|
// mem-bit 5, mem-bit 7, chip-bit 4: defines chip type
|
||||||
uint8_t k16 = isset(mem_cfg, 0x80);
|
uint8_t k16 = isset(mem_cfg, 0x80);
|
||||||
//uint8_t k2 = isset(mem_cfg, 0x08);
|
//uint8_t k2 = isset(mem_cfg, 0x08);
|
||||||
uint8_t book = isset(mem_cfg, 0x20);
|
uint8_t book = isset(mem_cfg, 0x20);
|
||||||
|
|
||||||
if(isset(chip_cfg, 0x10) && !k16 && !book) {
|
if(isset(chip_cfg, 0x10) && !k16 && !book) {
|
||||||
*kb = 2;
|
*kb = 2;
|
||||||
*app_areas = 2;
|
*app_areas = 2;
|
||||||
*max_blk = 31;
|
*max_blk = 31;
|
||||||
} else if(isset(chip_cfg, 0x10) && k16 && !book) {
|
} else if(isset(chip_cfg, 0x10) && k16 && !book) {
|
||||||
*kb = 16;
|
*kb = 16;
|
||||||
*app_areas = 2;
|
*app_areas = 2;
|
||||||
*max_blk = 255; //16kb
|
*max_blk = 255; //16kb
|
||||||
} else if(notset(chip_cfg, 0x10) && !k16 && !book) {
|
} else if(notset(chip_cfg, 0x10) && !k16 && !book) {
|
||||||
*kb = 16;
|
*kb = 16;
|
||||||
*app_areas = 16;
|
*app_areas = 16;
|
||||||
*max_blk = 255; //16kb
|
*max_blk = 255; //16kb
|
||||||
} else if(isset(chip_cfg, 0x10) && k16 && book) {
|
} else if(isset(chip_cfg, 0x10) && k16 && book) {
|
||||||
*kb = 32;
|
*kb = 32;
|
||||||
*app_areas = 3;
|
*app_areas = 3;
|
||||||
*max_blk = 255; //16kb
|
*max_blk = 255; //16kb
|
||||||
} else if(notset(chip_cfg, 0x10) && !k16 && book) {
|
} else if(notset(chip_cfg, 0x10) && !k16 && book) {
|
||||||
*kb = 32;
|
*kb = 32;
|
||||||
*app_areas = 17;
|
*app_areas = 17;
|
||||||
*max_blk = 255; //16kb
|
*max_blk = 255; //16kb
|
||||||
} else {
|
} else {
|
||||||
*kb = 32;
|
*kb = 32;
|
||||||
*app_areas = 2;
|
*app_areas = 2;
|
||||||
*max_blk = 255;
|
*max_blk = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mem_app_config(const picopass_hdr *hdr) {
|
void mem_app_config(const picopass_hdr *hdr) {
|
||||||
uint8_t mem = hdr->conf.mem_config;
|
uint8_t mem = hdr->conf.mem_config;
|
||||||
uint8_t chip = hdr->conf.chip_config;
|
uint8_t chip = hdr->conf.chip_config;
|
||||||
uint8_t applimit = hdr->conf.app_limit;
|
uint8_t applimit = hdr->conf.app_limit;
|
||||||
uint8_t kb = 2;
|
uint8_t kb = 2;
|
||||||
uint8_t app_areas = 2;
|
uint8_t app_areas = 2;
|
||||||
uint8_t max_blk = 31;
|
uint8_t max_blk = 31;
|
||||||
|
|
||||||
getMemConfig(mem, chip, &max_blk, &app_areas, &kb);
|
getMemConfig(mem, chip, &max_blk, &app_areas, &kb);
|
||||||
|
|
||||||
if (applimit < 6) applimit = 26;
|
if (applimit < 6) applimit = 26;
|
||||||
if (kb == 2 && (applimit > 0x1f) ) applimit = 26;
|
if (kb == 2 && (applimit > 0x1f) ) applimit = 26;
|
||||||
|
|
||||||
PrintAndLogDevice(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem);
|
PrintAndLogDevice(NORMAL, " Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem);
|
||||||
PrintAndLogDevice(NORMAL, "\tAA1: blocks 06-%02X", applimit);
|
PrintAndLogDevice(NORMAL, "\tAA1: blocks 06-%02X", applimit);
|
||||||
PrintAndLogDevice(NORMAL, "\tAA2: blocks %02X-%02X", applimit+1, max_blk);
|
PrintAndLogDevice(NORMAL, "\tAA2: blocks %02X-%02X", applimit+1, max_blk);
|
||||||
PrintAndLogDevice(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]);
|
PrintAndLogDevice(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]);
|
||||||
PrintAndLogDevice(NORMAL, "\nKeyAccess:");
|
PrintAndLogDevice(NORMAL, "\nKeyAccess:");
|
||||||
|
|
||||||
uint8_t book = isset(mem, 0x20);
|
uint8_t book = isset(mem, 0x20);
|
||||||
if (book) {
|
if (book) {
|
||||||
PrintAndLogDevice(NORMAL, "\tRead A - Kd");
|
PrintAndLogDevice(NORMAL, "\tRead A - Kd");
|
||||||
PrintAndLogDevice(NORMAL, "\tRead B - Kc");
|
PrintAndLogDevice(NORMAL, "\tRead B - Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tWrite A - Kd");
|
PrintAndLogDevice(NORMAL, "\tWrite A - Kd");
|
||||||
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
|
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
|
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
|
||||||
PrintAndLogDevice(NORMAL,"\tCredit - Kc");
|
PrintAndLogDevice(NORMAL,"\tCredit - Kc");
|
||||||
} else{
|
} else{
|
||||||
PrintAndLogDevice(NORMAL, "\tRead A - Kd or Kc");
|
PrintAndLogDevice(NORMAL, "\tRead A - Kd or Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tRead B - Kd or Kc");
|
PrintAndLogDevice(NORMAL, "\tRead B - Kd or Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tWrite A - Kc");
|
PrintAndLogDevice(NORMAL, "\tWrite A - Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
|
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
|
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
|
||||||
PrintAndLogDevice(NORMAL, "\tCredit - Kc");
|
PrintAndLogDevice(NORMAL, "\tCredit - Kc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void print_picopass_info(const picopass_hdr *hdr) {
|
void print_picopass_info(const picopass_hdr *hdr) {
|
||||||
fuse_config(hdr);
|
fuse_config(hdr);
|
||||||
mem_app_config(hdr);
|
mem_app_config(hdr);
|
||||||
}
|
}
|
||||||
void printIclassDumpInfo(uint8_t* iclass_dump) {
|
void printIclassDumpInfo(uint8_t* iclass_dump) {
|
||||||
print_picopass_info((picopass_hdr *) iclass_dump);
|
print_picopass_info((picopass_hdr *) iclass_dump);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define PrintAndLogDevice(level, format, ...) { }
|
#define PrintAndLogDevice(level, format, ...) { }
|
||||||
#endif
|
#endif
|
||||||
//ON_DEVICE
|
//ON_DEVICE
|
||||||
|
|
|
@ -9,115 +9,115 @@
|
||||||
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
|
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
|
||||||
/*
|
/*
|
||||||
ISO14443A (usually NFC tags)
|
ISO14443A (usually NFC tags)
|
||||||
26 (7bits) = REQA
|
26 (7bits) = REQA
|
||||||
30 = Read (usage: 30+1byte block number+2bytes ISO14443A-CRC - answer: 16bytes)
|
30 = Read (usage: 30+1byte block number+2bytes ISO14443A-CRC - answer: 16bytes)
|
||||||
A2 = Write (usage: A2+1byte block number+4bytes data+2bytes ISO14443A-CRC - answer: 0A [ACK] or 00 [NAK])
|
A2 = Write (usage: A2+1byte block number+4bytes data+2bytes ISO14443A-CRC - answer: 0A [ACK] or 00 [NAK])
|
||||||
52 (7bits) = WUPA (usage: 52(7bits) - answer: 2bytes ATQA)
|
52 (7bits) = WUPA (usage: 52(7bits) - answer: 2bytes ATQA)
|
||||||
93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
|
93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
|
||||||
93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
|
93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
|
||||||
95 20 = Anticollision of cascade level2
|
95 20 = Anticollision of cascade level2
|
||||||
95 70 = Select of cascade level2
|
95 70 = Select of cascade level2
|
||||||
50 00 = Halt (usage: 5000+2bytes ISO14443A-CRC - no answer from card)
|
50 00 = Halt (usage: 5000+2bytes ISO14443A-CRC - no answer from card)
|
||||||
Mifare
|
Mifare
|
||||||
60 = Authenticate with KeyA
|
60 = Authenticate with KeyA
|
||||||
61 = Authenticate with KeyB
|
61 = Authenticate with KeyB
|
||||||
40 (7bits) = Used to put Chinese Changeable UID cards in special mode (must be followed by 43 (8bits) - answer: 0A)
|
40 (7bits) = Used to put Chinese Changeable UID cards in special mode (must be followed by 43 (8bits) - answer: 0A)
|
||||||
C0 = Decrement
|
C0 = Decrement
|
||||||
C1 = Increment
|
C1 = Increment
|
||||||
C2 = Restore
|
C2 = Restore
|
||||||
B0 = Transfer
|
B0 = Transfer
|
||||||
Ultralight C
|
Ultralight C
|
||||||
A0 = Compatibility Write (to accomodate MIFARE commands)
|
A0 = Compatibility Write (to accomodate MIFARE commands)
|
||||||
1A = Step1 Authenticate
|
1A = Step1 Authenticate
|
||||||
AF = Step2 Authenticate
|
AF = Step2 Authenticate
|
||||||
|
|
||||||
|
|
||||||
ISO14443B
|
ISO14443B
|
||||||
05 = REQB
|
05 = REQB
|
||||||
1D = ATTRIB
|
1D = ATTRIB
|
||||||
50 = HALT
|
50 = HALT
|
||||||
|
|
||||||
BA = PING (reader -> tag)
|
BA = PING (reader -> tag)
|
||||||
AB = PONG (tag -> reader)
|
AB = PONG (tag -> reader)
|
||||||
SRIX4K (tag does not respond to 05)
|
SRIX4K (tag does not respond to 05)
|
||||||
06 00 = INITIATE
|
06 00 = INITIATE
|
||||||
0E xx = SELECT ID (xx = Chip-ID)
|
0E xx = SELECT ID (xx = Chip-ID)
|
||||||
0B = Get UID
|
0B = Get UID
|
||||||
08 yy = Read Block (yy = block number)
|
08 yy = Read Block (yy = block number)
|
||||||
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
||||||
0C = Reset to Inventory
|
0C = Reset to Inventory
|
||||||
0F = Completion
|
0F = Completion
|
||||||
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
||||||
|
|
||||||
|
|
||||||
ISO15693
|
ISO15693
|
||||||
MANDATORY COMMANDS (all ISO15693 tags must support those)
|
MANDATORY COMMANDS (all ISO15693 tags must support those)
|
||||||
01 = Inventory (usage: 260100+2bytes ISO15693-CRC - answer: 12bytes)
|
01 = Inventory (usage: 260100+2bytes ISO15693-CRC - answer: 12bytes)
|
||||||
02 = Stay Quiet
|
02 = Stay Quiet
|
||||||
OPTIONAL COMMANDS (not all tags support them)
|
OPTIONAL COMMANDS (not all tags support them)
|
||||||
20 = Read Block (usage: 0220+1byte block number+2bytes ISO15693-CRC - answer: 4bytes)
|
20 = Read Block (usage: 0220+1byte block number+2bytes ISO15693-CRC - answer: 4bytes)
|
||||||
21 = Write Block (usage: 0221+1byte block number+4bytes data+2bytes ISO15693-CRC - answer: 4bytes)
|
21 = Write Block (usage: 0221+1byte block number+4bytes data+2bytes ISO15693-CRC - answer: 4bytes)
|
||||||
22 = Lock Block
|
22 = Lock Block
|
||||||
23 = Read Multiple Blocks (usage: 0223+1byte 1st block to read+1byte last block to read+2bytes ISO15693-CRC)
|
23 = Read Multiple Blocks (usage: 0223+1byte 1st block to read+1byte last block to read+2bytes ISO15693-CRC)
|
||||||
25 = Select
|
25 = Select
|
||||||
26 = Reset to Ready
|
26 = Reset to Ready
|
||||||
27 = Write AFI
|
27 = Write AFI
|
||||||
28 = Lock AFI
|
28 = Lock AFI
|
||||||
29 = Write DSFID
|
29 = Write DSFID
|
||||||
2A = Lock DSFID
|
2A = Lock DSFID
|
||||||
2B = Get_System_Info (usage: 022B+2bytes ISO15693-CRC - answer: 14 or more bytes)
|
2B = Get_System_Info (usage: 022B+2bytes ISO15693-CRC - answer: 14 or more bytes)
|
||||||
2C = Read Multiple Block Security Status (usage: 022C+1byte 1st block security to read+1byte last block security to read+2bytes ISO15693-CRC)
|
2C = Read Multiple Block Security Status (usage: 022C+1byte 1st block security to read+1byte last block security to read+2bytes ISO15693-CRC)
|
||||||
|
|
||||||
EM Microelectronic CUSTOM COMMANDS
|
EM Microelectronic CUSTOM COMMANDS
|
||||||
A5 = Active EAS (followed by 1byte IC Manufacturer code+1byte EAS type)
|
A5 = Active EAS (followed by 1byte IC Manufacturer code+1byte EAS type)
|
||||||
A7 = Write EAS ID (followed by 1byte IC Manufacturer code+2bytes EAS value)
|
A7 = Write EAS ID (followed by 1byte IC Manufacturer code+2bytes EAS value)
|
||||||
B8 = Get Protection Status for a specific block (followed by 1byte IC Manufacturer code+1byte block number+1byte of how many blocks after the previous is needed the info)
|
B8 = Get Protection Status for a specific block (followed by 1byte IC Manufacturer code+1byte block number+1byte of how many blocks after the previous is needed the info)
|
||||||
E4 = Login (followed by 1byte IC Manufacturer code+4bytes password)
|
E4 = Login (followed by 1byte IC Manufacturer code+4bytes password)
|
||||||
NXP/Philips CUSTOM COMMANDS
|
NXP/Philips CUSTOM COMMANDS
|
||||||
A0 = Inventory Read
|
A0 = Inventory Read
|
||||||
A1 = Fast Inventory Read
|
A1 = Fast Inventory Read
|
||||||
A2 = Set EAS
|
A2 = Set EAS
|
||||||
A3 = Reset EAS
|
A3 = Reset EAS
|
||||||
A4 = Lock EAS
|
A4 = Lock EAS
|
||||||
A5 = EAS Alarm
|
A5 = EAS Alarm
|
||||||
A6 = Password Protect EAS
|
A6 = Password Protect EAS
|
||||||
A7 = Write EAS ID
|
A7 = Write EAS ID
|
||||||
A8 = Read EPC
|
A8 = Read EPC
|
||||||
B0 = Inventory Page Read
|
B0 = Inventory Page Read
|
||||||
B1 = Fast Inventory Page Read
|
B1 = Fast Inventory Page Read
|
||||||
B2 = Get Random Number
|
B2 = Get Random Number
|
||||||
B3 = Set Password
|
B3 = Set Password
|
||||||
B4 = Write Password
|
B4 = Write Password
|
||||||
B5 = Lock Password
|
B5 = Lock Password
|
||||||
B6 = Bit Password Protection
|
B6 = Bit Password Protection
|
||||||
B7 = Lock Page Protection Condition
|
B7 = Lock Page Protection Condition
|
||||||
B8 = Get Multiple Block Protection Status
|
B8 = Get Multiple Block Protection Status
|
||||||
B9 = Destroy SLI
|
B9 = Destroy SLI
|
||||||
BA = Enable Privacy
|
BA = Enable Privacy
|
||||||
BB = 64bit Password Protection
|
BB = 64bit Password Protection
|
||||||
40 = Long Range CMD (Standard ISO/TR7003:1990)
|
40 = Long Range CMD (Standard ISO/TR7003:1990)
|
||||||
|
|
||||||
ISO 7816-4 Basic interindustry commands. For command APDU's.
|
ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
B0 = READ BINARY
|
B0 = READ BINARY
|
||||||
D0 = WRITE BINARY
|
D0 = WRITE BINARY
|
||||||
D6 = UPDATE BINARY
|
D6 = UPDATE BINARY
|
||||||
0E = ERASE BINARY
|
0E = ERASE BINARY
|
||||||
B2 = READ RECORDS
|
B2 = READ RECORDS
|
||||||
D2 = WRITE RECORDS
|
D2 = WRITE RECORDS
|
||||||
E2 = APPEND RECORD
|
E2 = APPEND RECORD
|
||||||
DC = UPDATE RECORD
|
DC = UPDATE RECORD
|
||||||
CA = GET DATA
|
CA = GET DATA
|
||||||
DA = PUT DATA
|
DA = PUT DATA
|
||||||
A4 = SELECT FILE
|
A4 = SELECT FILE
|
||||||
20 = VERIFY
|
20 = VERIFY
|
||||||
88 = INTERNAL AUTHENTICATION
|
88 = INTERNAL AUTHENTICATION
|
||||||
82 = EXTERNAL AUTHENTICATION
|
82 = EXTERNAL AUTHENTICATION
|
||||||
B4 = GET CHALLENGE
|
B4 = GET CHALLENGE
|
||||||
70 = MANAGE CHANNEL
|
70 = MANAGE CHANNEL
|
||||||
|
|
||||||
For response APDU's
|
For response APDU's
|
||||||
90 00 = OK
|
90 00 = OK
|
||||||
6x xx = ERROR
|
6x xx = ERROR
|
||||||
*/
|
*/
|
||||||
// these cmds are adjusted to ISO15693 and Manchester encoding requests.
|
// these cmds are adjusted to ISO15693 and Manchester encoding requests.
|
||||||
// for instance ICLASS_CMD_SELECT 0x81 tells if ISO14443b/BPSK coding/106 kbits/s
|
// for instance ICLASS_CMD_SELECT 0x81 tells if ISO14443b/BPSK coding/106 kbits/s
|
||||||
|
@ -134,62 +134,62 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
|
|
||||||
#define ICLASS_CMD_SELECT 0x81
|
#define ICLASS_CMD_SELECT 0x81
|
||||||
#define ICLASS_CMD_PAGESEL 0x84
|
#define ICLASS_CMD_PAGESEL 0x84
|
||||||
#define ICLASS_CMD_UPDATE 0x87
|
#define ICLASS_CMD_UPDATE 0x87
|
||||||
#define ICLASS_CMD_READCHECK_KC 0x18
|
#define ICLASS_CMD_READCHECK_KC 0x18
|
||||||
#define ICLASS_CMD_READCHECK_KD 0x88
|
#define ICLASS_CMD_READCHECK_KD 0x88
|
||||||
#define ICLASS_CMD_ACT 0x8E
|
#define ICLASS_CMD_ACT 0x8E
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define ISO14443A_CMD_REQA 0x26
|
#define ISO14443A_CMD_REQA 0x26
|
||||||
#define ISO14443A_CMD_READBLOCK 0x30
|
#define ISO14443A_CMD_READBLOCK 0x30
|
||||||
#define ISO14443A_CMD_WUPA 0x52
|
#define ISO14443A_CMD_WUPA 0x52
|
||||||
#define ISO14443A_CMD_OPTS 0x35
|
#define ISO14443A_CMD_OPTS 0x35
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
|
||||||
#define ISO14443A_CMD_WRITEBLOCK 0xA0
|
#define ISO14443A_CMD_WRITEBLOCK 0xA0
|
||||||
#define ISO14443A_CMD_HALT 0x50
|
#define ISO14443A_CMD_HALT 0x50
|
||||||
#define ISO14443A_CMD_RATS 0xE0
|
#define ISO14443A_CMD_RATS 0xE0
|
||||||
|
|
||||||
#define MIFARE_AUTH_KEYA 0x60
|
#define MIFARE_AUTH_KEYA 0x60
|
||||||
#define MIFARE_AUTH_KEYB 0x61
|
#define MIFARE_AUTH_KEYB 0x61
|
||||||
#define MIFARE_MAGICWUPC1 0x40
|
#define MIFARE_MAGICWUPC1 0x40
|
||||||
#define MIFARE_MAGICWUPC2 0x43
|
#define MIFARE_MAGICWUPC2 0x43
|
||||||
#define MIFARE_MAGICWIPEC 0x41
|
#define MIFARE_MAGICWIPEC 0x41
|
||||||
#define MIFARE_CMD_INC 0xC0
|
#define MIFARE_CMD_INC 0xC0
|
||||||
#define MIFARE_CMD_DEC 0xC1
|
#define MIFARE_CMD_DEC 0xC1
|
||||||
#define MIFARE_CMD_RESTORE 0xC2
|
#define MIFARE_CMD_RESTORE 0xC2
|
||||||
#define MIFARE_CMD_TRANSFER 0xB0
|
#define MIFARE_CMD_TRANSFER 0xB0
|
||||||
|
|
||||||
#define MIFARE_EV1_PERSONAL_UID 0x40
|
#define MIFARE_EV1_PERSONAL_UID 0x40
|
||||||
#define MIFARE_EV1_SETMODE 0x43
|
#define MIFARE_EV1_SETMODE 0x43
|
||||||
|
|
||||||
#define MIFARE_ULC_WRITE 0xA2
|
#define MIFARE_ULC_WRITE 0xA2
|
||||||
//#define MIFARE_ULC__COMP_WRITE 0xA0
|
//#define MIFARE_ULC__COMP_WRITE 0xA0
|
||||||
#define MIFARE_ULC_AUTH_1 0x1A
|
#define MIFARE_ULC_AUTH_1 0x1A
|
||||||
#define MIFARE_ULC_AUTH_2 0xAF
|
#define MIFARE_ULC_AUTH_2 0xAF
|
||||||
|
|
||||||
#define MIFARE_ULEV1_AUTH 0x1B
|
#define MIFARE_ULEV1_AUTH 0x1B
|
||||||
#define MIFARE_ULEV1_VERSION 0x60
|
#define MIFARE_ULEV1_VERSION 0x60
|
||||||
#define MIFARE_ULEV1_FASTREAD 0x3A
|
#define MIFARE_ULEV1_FASTREAD 0x3A
|
||||||
#define MIFARE_ULEV1_READ_CNT 0x39
|
#define MIFARE_ULEV1_READ_CNT 0x39
|
||||||
#define MIFARE_ULEV1_INCR_CNT 0xA5
|
#define MIFARE_ULEV1_INCR_CNT 0xA5
|
||||||
#define MIFARE_ULEV1_READSIG 0x3C
|
#define MIFARE_ULEV1_READSIG 0x3C
|
||||||
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
||||||
#define MIFARE_ULEV1_VCSL 0x4B
|
#define MIFARE_ULEV1_VCSL 0x4B
|
||||||
|
|
||||||
// New Mifare UL Nano commands. Ref:: (https://www.nxp.com/docs/en/data-sheet/MF0UN_H_00.pdf)
|
// New Mifare UL Nano commands. Ref:: (https://www.nxp.com/docs/en/data-sheet/MF0UN_H_00.pdf)
|
||||||
#define MIFARE_ULNANO_WRITESIG 0xA9
|
#define MIFARE_ULNANO_WRITESIG 0xA9
|
||||||
#define MIFARE_ULNANO_LOCKSIF 0xAC
|
#define MIFARE_ULNANO_LOCKSIF 0xAC
|
||||||
|
|
||||||
// mifare 4bit card answers
|
// mifare 4bit card answers
|
||||||
#define CARD_ACK 0x0A // 1010 - ACK
|
#define CARD_ACK 0x0A // 1010 - ACK
|
||||||
#define CARD_NACK_IV 0x00 // 0000 - NACK, invalid argument (invalid page address)
|
#define CARD_NACK_IV 0x00 // 0000 - NACK, invalid argument (invalid page address)
|
||||||
#define CARD_NACK_PA 0x01 // 0001 - NACK, parity / crc error
|
#define CARD_NACK_PA 0x01 // 0001 - NACK, parity / crc error
|
||||||
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
|
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
|
||||||
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
|
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
|
||||||
#define CARD_NACK_EE 0x07 // 0111 - NACK, EEPROM write error
|
#define CARD_NACK_EE 0x07 // 0111 - NACK, EEPROM write error
|
||||||
|
|
||||||
// Magic Generation 1, parameter "work flags"
|
// Magic Generation 1, parameter "work flags"
|
||||||
// bit 0 - need get UID
|
// bit 0 - need get UID
|
||||||
|
@ -198,14 +198,14 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
// bit 3 - turn on FPGA
|
// bit 3 - turn on FPGA
|
||||||
// bit 4 - turn off FPGA
|
// bit 4 - turn off FPGA
|
||||||
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
#define MAGIC_UID 0x01
|
#define MAGIC_UID 0x01
|
||||||
#define MAGIC_WUPC 0x02
|
#define MAGIC_WUPC 0x02
|
||||||
#define MAGIC_HALT 0x04
|
#define MAGIC_HALT 0x04
|
||||||
#define MAGIC_INIT 0x08
|
#define MAGIC_INIT 0x08
|
||||||
#define MAGIC_OFF 0x10
|
#define MAGIC_OFF 0x10
|
||||||
#define MAGIC_DATAIN 0x20
|
#define MAGIC_DATAIN 0x20
|
||||||
#define MAGIC_WIPE 0x40
|
#define MAGIC_WIPE 0x40
|
||||||
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
||||||
|
|
||||||
/**
|
/**
|
||||||
06 00 = INITIATE
|
06 00 = INITIATE
|
||||||
|
@ -229,8 +229,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define ISO14443B_RESET 0x0C
|
#define ISO14443B_RESET 0x0C
|
||||||
#define ISO14443B_COMPLETION 0x0F
|
#define ISO14443B_COMPLETION 0x0F
|
||||||
#define ISO14443B_AUTHENTICATE 0x0A
|
#define ISO14443B_AUTHENTICATE 0x0A
|
||||||
#define ISO14443B_PING 0xBA
|
#define ISO14443B_PING 0xBA
|
||||||
#define ISO14443B_PONG 0xAB
|
#define ISO14443B_PONG 0xAB
|
||||||
|
|
||||||
//First byte is 26
|
//First byte is 26
|
||||||
#define ISO15693_INVENTORY 0x01
|
#define ISO15693_INVENTORY 0x01
|
||||||
|
@ -251,31 +251,31 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
|
|
||||||
|
|
||||||
// Topaz command set:
|
// Topaz command set:
|
||||||
#define TOPAZ_REQA 0x26 // Request
|
#define TOPAZ_REQA 0x26 // Request
|
||||||
#define TOPAZ_WUPA 0x52 // WakeUp
|
#define TOPAZ_WUPA 0x52 // WakeUp
|
||||||
#define TOPAZ_RID 0x78 // Read ID
|
#define TOPAZ_RID 0x78 // Read ID
|
||||||
#define TOPAZ_RALL 0x00 // Read All (all bytes)
|
#define TOPAZ_RALL 0x00 // Read All (all bytes)
|
||||||
#define TOPAZ_READ 0x01 // Read (a single byte)
|
#define TOPAZ_READ 0x01 // Read (a single byte)
|
||||||
#define TOPAZ_WRITE_E 0x53 // Write-with-erase (a single byte)
|
#define TOPAZ_WRITE_E 0x53 // Write-with-erase (a single byte)
|
||||||
#define TOPAZ_WRITE_NE 0x1a // Write-no-erase (a single byte)
|
#define TOPAZ_WRITE_NE 0x1a // Write-no-erase (a single byte)
|
||||||
// additional commands for Dynamic Memory Model
|
// additional commands for Dynamic Memory Model
|
||||||
#define TOPAZ_RSEG 0x10 // Read segment
|
#define TOPAZ_RSEG 0x10 // Read segment
|
||||||
#define TOPAZ_READ8 0x02 // Read (eight bytes)
|
#define TOPAZ_READ8 0x02 // Read (eight bytes)
|
||||||
#define TOPAZ_WRITE_E8 0x54 // Write-with-erase (eight bytes)
|
#define TOPAZ_WRITE_E8 0x54 // Write-with-erase (eight bytes)
|
||||||
#define TOPAZ_WRITE_NE8 0x1B // Write-no-erase (eight bytes)
|
#define TOPAZ_WRITE_NE8 0x1B // Write-no-erase (eight bytes)
|
||||||
|
|
||||||
|
|
||||||
// Definitions of which protocol annotations there are available
|
// Definitions of which protocol annotations there are available
|
||||||
#define ISO_14443A 0
|
#define ISO_14443A 0
|
||||||
#define ICLASS 1
|
#define ICLASS 1
|
||||||
#define ISO_14443B 2
|
#define ISO_14443B 2
|
||||||
#define TOPAZ 3
|
#define TOPAZ 3
|
||||||
#define ISO_7816_4 4
|
#define ISO_7816_4 4
|
||||||
#define MFDES 5
|
#define MFDES 5
|
||||||
#define LEGIC 6
|
#define LEGIC 6
|
||||||
#define ISO_15693 7
|
#define ISO_15693 7
|
||||||
#define FELICA 8
|
#define FELICA 8
|
||||||
#define PROTO_MIFARE 9
|
#define PROTO_MIFARE 9
|
||||||
|
|
||||||
//-- Picopass fuses
|
//-- Picopass fuses
|
||||||
#define FUSE_FPERS 0x80
|
#define FUSE_FPERS 0x80
|
||||||
|
@ -288,131 +288,131 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define FUSE_RA 0x01
|
#define FUSE_RA 0x01
|
||||||
|
|
||||||
// ISO 7816-4 Basic interindustry commands. For command APDU's.
|
// ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define ISO7816_READ_BINARY 0xB0
|
#define ISO7816_READ_BINARY 0xB0
|
||||||
#define ISO7816_WRITE_BINARY 0xD0
|
#define ISO7816_WRITE_BINARY 0xD0
|
||||||
#define ISO7816_UPDATE_BINARY 0xD6
|
#define ISO7816_UPDATE_BINARY 0xD6
|
||||||
#define ISO7816_ERASE_BINARY 0x0E
|
#define ISO7816_ERASE_BINARY 0x0E
|
||||||
#define ISO7816_READ_RECORDS 0xB2
|
#define ISO7816_READ_RECORDS 0xB2
|
||||||
#define ISO7816_WRITE_RECORDS 0xD2
|
#define ISO7816_WRITE_RECORDS 0xD2
|
||||||
#define ISO7816_APPEND_RECORD 0xE2
|
#define ISO7816_APPEND_RECORD 0xE2
|
||||||
#define ISO7816_UPDATE_RECORD 0xDC
|
#define ISO7816_UPDATE_RECORD 0xDC
|
||||||
#define ISO7816_GET_DATA 0xCA
|
#define ISO7816_GET_DATA 0xCA
|
||||||
#define ISO7816_PUT_DATA 0xDA
|
#define ISO7816_PUT_DATA 0xDA
|
||||||
#define ISO7816_SELECT_FILE 0xA4
|
#define ISO7816_SELECT_FILE 0xA4
|
||||||
#define ISO7816_VERIFY 0x20
|
#define ISO7816_VERIFY 0x20
|
||||||
#define ISO7816_INTERNAL_AUTHENTICATION 0x88
|
#define ISO7816_INTERNAL_AUTHENTICATION 0x88
|
||||||
#define ISO7816_EXTERNAL_AUTHENTICATION 0x82
|
#define ISO7816_EXTERNAL_AUTHENTICATION 0x82
|
||||||
#define ISO7816_GET_CHALLENGE 0x84
|
#define ISO7816_GET_CHALLENGE 0x84
|
||||||
#define ISO7816_MANAGE_CHANNEL 0x70
|
#define ISO7816_MANAGE_CHANNEL 0x70
|
||||||
|
|
||||||
#define ISO7816_GET_RESPONSE 0xC0
|
#define ISO7816_GET_RESPONSE 0xC0
|
||||||
// ISO7816-4 For response APDU's
|
// ISO7816-4 For response APDU's
|
||||||
#define ISO7816_OK 0x9000
|
#define ISO7816_OK 0x9000
|
||||||
// 6x xx = ERROR
|
// 6x xx = ERROR
|
||||||
|
|
||||||
// MIFARE DESFire command set:
|
// MIFARE DESFire command set:
|
||||||
#define MFDES_CREATE_APPLICATION 0xca
|
#define MFDES_CREATE_APPLICATION 0xca
|
||||||
#define MFDES_DELETE_APPLICATION 0xda
|
#define MFDES_DELETE_APPLICATION 0xda
|
||||||
#define MFDES_GET_APPLICATION_IDS 0x6a
|
#define MFDES_GET_APPLICATION_IDS 0x6a
|
||||||
#define MFDES_SELECT_APPLICATION 0x5a
|
#define MFDES_SELECT_APPLICATION 0x5a
|
||||||
#define MFDES_FORMAT_PICC 0xfc
|
#define MFDES_FORMAT_PICC 0xfc
|
||||||
#define MFDES_GET_VERSION 0x60
|
#define MFDES_GET_VERSION 0x60
|
||||||
#define MFDES_READ_DATA 0xbd
|
#define MFDES_READ_DATA 0xbd
|
||||||
#define MFDES_WRITE_DATA 0x3d
|
#define MFDES_WRITE_DATA 0x3d
|
||||||
#define MFDES_GET_VALUE 0x6c
|
#define MFDES_GET_VALUE 0x6c
|
||||||
#define MFDES_CREDIT 0x0c
|
#define MFDES_CREDIT 0x0c
|
||||||
#define MFDES_DEBIT 0xdc
|
#define MFDES_DEBIT 0xdc
|
||||||
#define MFDES_LIMITED_CREDIT 0x1c
|
#define MFDES_LIMITED_CREDIT 0x1c
|
||||||
#define MFDES_WRITE_RECORD 0x3b
|
#define MFDES_WRITE_RECORD 0x3b
|
||||||
#define MFDES_READ_RECORDS 0xbb
|
#define MFDES_READ_RECORDS 0xbb
|
||||||
#define MFDES_CLEAR_RECORD_FILE 0xeb
|
#define MFDES_CLEAR_RECORD_FILE 0xeb
|
||||||
#define MFDES_COMMIT_TRANSACTION 0xc7
|
#define MFDES_COMMIT_TRANSACTION 0xc7
|
||||||
#define MFDES_ABORT_TRANSACTION 0xa7
|
#define MFDES_ABORT_TRANSACTION 0xa7
|
||||||
#define MFDES_GET_FREE_MEMORY 0x6e
|
#define MFDES_GET_FREE_MEMORY 0x6e
|
||||||
#define MFDES_GET_FILE_IDS 0x6f
|
#define MFDES_GET_FILE_IDS 0x6f
|
||||||
#define MFDES_GET_ISOFILE_IDS 0x61
|
#define MFDES_GET_ISOFILE_IDS 0x61
|
||||||
#define MFDES_GET_FILE_SETTINGS 0xf5
|
#define MFDES_GET_FILE_SETTINGS 0xf5
|
||||||
#define MFDES_CHANGE_FILE_SETTINGS 0x5f
|
#define MFDES_CHANGE_FILE_SETTINGS 0x5f
|
||||||
#define MFDES_CREATE_STD_DATA_FILE 0xcd
|
#define MFDES_CREATE_STD_DATA_FILE 0xcd
|
||||||
#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb
|
#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb
|
||||||
#define MFDES_CREATE_VALUE_FILE 0xcc
|
#define MFDES_CREATE_VALUE_FILE 0xcc
|
||||||
#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1
|
#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1
|
||||||
#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0
|
#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0
|
||||||
#define MFDES_DELETE_FILE 0xdf
|
#define MFDES_DELETE_FILE 0xdf
|
||||||
#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE
|
#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE
|
||||||
#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD
|
#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD
|
||||||
#define MFDES_AUTHENTICATE_AES 0xaa
|
#define MFDES_AUTHENTICATE_AES 0xaa
|
||||||
#define MFDES_CHANGE_KEY_SETTINGS 0x54
|
#define MFDES_CHANGE_KEY_SETTINGS 0x54
|
||||||
#define MFDES_GET_KEY_SETTINGS 0x45
|
#define MFDES_GET_KEY_SETTINGS 0x45
|
||||||
#define MFDES_CHANGE_KEY 0xc4
|
#define MFDES_CHANGE_KEY 0xc4
|
||||||
#define MFDES_GET_KEY_VERSION 0x64
|
#define MFDES_GET_KEY_VERSION 0x64
|
||||||
#define MFDES_AUTHENTICATION_FRAME 0xAF
|
#define MFDES_AUTHENTICATION_FRAME 0xAF
|
||||||
|
|
||||||
// LEGIC Commands
|
// LEGIC Commands
|
||||||
#define LEGIC_MIM_22 0x0D
|
#define LEGIC_MIM_22 0x0D
|
||||||
#define LEGIC_MIM_256 0x1D
|
#define LEGIC_MIM_256 0x1D
|
||||||
#define LEGIC_MIM_1024 0x3D
|
#define LEGIC_MIM_1024 0x3D
|
||||||
#define LEGIC_ACK_22 0x19
|
#define LEGIC_ACK_22 0x19
|
||||||
#define LEGIC_ACK_256 0x39
|
#define LEGIC_ACK_256 0x39
|
||||||
#define LEGIC_READ 0x01
|
#define LEGIC_READ 0x01
|
||||||
#define LEGIC_WRITE 0x00
|
#define LEGIC_WRITE 0x00
|
||||||
|
|
||||||
void printIclassDumpInfo(uint8_t* iclass_dump);
|
void printIclassDumpInfo(uint8_t* iclass_dump);
|
||||||
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
|
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
|
||||||
|
|
||||||
/* T55x7 configuration register definitions */
|
/* T55x7 configuration register definitions */
|
||||||
#define T55x7_POR_DELAY 0x00000001
|
#define T55x7_POR_DELAY 0x00000001
|
||||||
#define T55x7_ST_TERMINATOR 0x00000008
|
#define T55x7_ST_TERMINATOR 0x00000008
|
||||||
#define T55x7_PWD 0x00000010
|
#define T55x7_PWD 0x00000010
|
||||||
#define T55x7_MAXBLOCK_SHIFT 5
|
#define T55x7_MAXBLOCK_SHIFT 5
|
||||||
#define T55x7_AOR 0x00000200
|
#define T55x7_AOR 0x00000200
|
||||||
#define T55x7_PSKCF_RF_2 0
|
#define T55x7_PSKCF_RF_2 0
|
||||||
#define T55x7_PSKCF_RF_4 0x00000400
|
#define T55x7_PSKCF_RF_4 0x00000400
|
||||||
#define T55x7_PSKCF_RF_8 0x00000800
|
#define T55x7_PSKCF_RF_8 0x00000800
|
||||||
#define T55x7_MODULATION_DIRECT 0
|
#define T55x7_MODULATION_DIRECT 0
|
||||||
#define T55x7_MODULATION_PSK1 0x00001000
|
#define T55x7_MODULATION_PSK1 0x00001000
|
||||||
#define T55x7_MODULATION_PSK2 0x00002000
|
#define T55x7_MODULATION_PSK2 0x00002000
|
||||||
#define T55x7_MODULATION_PSK3 0x00003000
|
#define T55x7_MODULATION_PSK3 0x00003000
|
||||||
#define T55x7_MODULATION_FSK1 0x00004000
|
#define T55x7_MODULATION_FSK1 0x00004000
|
||||||
#define T55x7_MODULATION_FSK2 0x00005000
|
#define T55x7_MODULATION_FSK2 0x00005000
|
||||||
#define T55x7_MODULATION_FSK1a 0x00006000
|
#define T55x7_MODULATION_FSK1a 0x00006000
|
||||||
#define T55x7_MODULATION_FSK2a 0x00007000
|
#define T55x7_MODULATION_FSK2a 0x00007000
|
||||||
#define T55x7_MODULATION_MANCHESTER 0x00008000
|
#define T55x7_MODULATION_MANCHESTER 0x00008000
|
||||||
#define T55x7_MODULATION_BIPHASE 0x00010000
|
#define T55x7_MODULATION_BIPHASE 0x00010000
|
||||||
#define T55x7_MODULATION_DIPHASE 0x00018000
|
#define T55x7_MODULATION_DIPHASE 0x00018000
|
||||||
#define T55x7_X_MODE 0x00020000
|
#define T55x7_X_MODE 0x00020000
|
||||||
#define T55x7_BITRATE_RF_8 0
|
#define T55x7_BITRATE_RF_8 0
|
||||||
#define T55x7_BITRATE_RF_16 0x00040000
|
#define T55x7_BITRATE_RF_16 0x00040000
|
||||||
#define T55x7_BITRATE_RF_32 0x00080000
|
#define T55x7_BITRATE_RF_32 0x00080000
|
||||||
#define T55x7_BITRATE_RF_40 0x000C0000
|
#define T55x7_BITRATE_RF_40 0x000C0000
|
||||||
#define T55x7_BITRATE_RF_50 0x00100000
|
#define T55x7_BITRATE_RF_50 0x00100000
|
||||||
#define T55x7_BITRATE_RF_64 0x00140000
|
#define T55x7_BITRATE_RF_64 0x00140000
|
||||||
#define T55x7_BITRATE_RF_100 0x00180000
|
#define T55x7_BITRATE_RF_100 0x00180000
|
||||||
#define T55x7_BITRATE_RF_128 0x001C0000
|
#define T55x7_BITRATE_RF_128 0x001C0000
|
||||||
#define T55x7_TESTMODE_DISABLED 0x60000000
|
#define T55x7_TESTMODE_DISABLED 0x60000000
|
||||||
|
|
||||||
/* T5555 (Q5) configuration register definitions */
|
/* T5555 (Q5) configuration register definitions */
|
||||||
#define T5555_ST_TERMINATOR 0x00000001
|
#define T5555_ST_TERMINATOR 0x00000001
|
||||||
#define T5555_MAXBLOCK_SHIFT 0x00000001
|
#define T5555_MAXBLOCK_SHIFT 0x00000001
|
||||||
#define T5555_MODULATION_MANCHESTER 0
|
#define T5555_MODULATION_MANCHESTER 0
|
||||||
#define T5555_MODULATION_PSK1 0x00000010
|
#define T5555_MODULATION_PSK1 0x00000010
|
||||||
#define T5555_MODULATION_PSK2 0x00000020
|
#define T5555_MODULATION_PSK2 0x00000020
|
||||||
#define T5555_MODULATION_PSK3 0x00000030
|
#define T5555_MODULATION_PSK3 0x00000030
|
||||||
#define T5555_MODULATION_FSK1 0x00000040
|
#define T5555_MODULATION_FSK1 0x00000040
|
||||||
#define T5555_MODULATION_FSK2 0x00000050
|
#define T5555_MODULATION_FSK2 0x00000050
|
||||||
#define T5555_MODULATION_BIPHASE 0x00000060
|
#define T5555_MODULATION_BIPHASE 0x00000060
|
||||||
#define T5555_MODULATION_DIRECT 0x00000070
|
#define T5555_MODULATION_DIRECT 0x00000070
|
||||||
#define T5555_INVERT_OUTPUT 0x00000080
|
#define T5555_INVERT_OUTPUT 0x00000080
|
||||||
#define T5555_PSK_RF_2 0
|
#define T5555_PSK_RF_2 0
|
||||||
#define T5555_PSK_RF_4 0x00000100
|
#define T5555_PSK_RF_4 0x00000100
|
||||||
#define T5555_PSK_RF_8 0x00000200
|
#define T5555_PSK_RF_8 0x00000200
|
||||||
#define T5555_USE_PWD 0x00000400
|
#define T5555_USE_PWD 0x00000400
|
||||||
#define T5555_USE_AOR 0x00000800
|
#define T5555_USE_AOR 0x00000800
|
||||||
#define T5555_SET_BITRATE(x) (((x-2)/2)<<12)
|
#define T5555_SET_BITRATE(x) (((x-2)/2)<<12)
|
||||||
#define T5555_GET_BITRATE(x) ((((x >> 12) & 0x3F)*2)+2)
|
#define T5555_GET_BITRATE(x) ((((x >> 12) & 0x3F)*2)+2)
|
||||||
#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2
|
#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2
|
||||||
#define T5555_FAST_WRITE 0x00004000
|
#define T5555_FAST_WRITE 0x00004000
|
||||||
#define T5555_PAGE_SELECT 0x00008000
|
#define T5555_PAGE_SELECT 0x00008000
|
||||||
|
|
||||||
#define T55XX_WRITE_TIMEOUT 1500
|
#define T55XX_WRITE_TIMEOUT 1500
|
||||||
|
|
||||||
|
@ -420,152 +420,152 @@ uint32_t GetT55xxClockBit(uint32_t clock);
|
||||||
|
|
||||||
|
|
||||||
// em4x05 & em4x69 chip configuration register definitions
|
// em4x05 & em4x69 chip configuration register definitions
|
||||||
#define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2)
|
#define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2)
|
||||||
#define EM4x05_SET_BITRATE(x) ((x-2)/2)
|
#define EM4x05_SET_BITRATE(x) ((x-2)/2)
|
||||||
#define EM4x05_MODULATION_NRZ 0x00000000
|
#define EM4x05_MODULATION_NRZ 0x00000000
|
||||||
#define EM4x05_MODULATION_MANCHESTER 0x00000040
|
#define EM4x05_MODULATION_MANCHESTER 0x00000040
|
||||||
#define EM4x05_MODULATION_BIPHASE 0x00000080
|
#define EM4x05_MODULATION_BIPHASE 0x00000080
|
||||||
#define EM4x05_MODULATION_MILLER 0x000000C0 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_MILLER 0x000000C0 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_MODULATION_PSK1 0x00000100 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_PSK1 0x00000100 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_MODULATION_PSK2 0x00000140 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_PSK2 0x00000140 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_MODULATION_PSK3 0x00000180 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_PSK3 0x00000180 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_MODULATION_FSK1 0x00000200 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_FSK1 0x00000200 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_MODULATION_FSK2 0x00000240 //not supported by all 4x05/4x69 chips
|
#define EM4x05_MODULATION_FSK2 0x00000240 //not supported by all 4x05/4x69 chips
|
||||||
#define EM4x05_PSK_RF_2 0
|
#define EM4x05_PSK_RF_2 0
|
||||||
#define EM4x05_PSK_RF_4 0x00000400
|
#define EM4x05_PSK_RF_4 0x00000400
|
||||||
#define EM4x05_PSK_RF_8 0x00000800
|
#define EM4x05_PSK_RF_8 0x00000800
|
||||||
#define EM4x05_MAXBLOCK_SHIFT 14
|
#define EM4x05_MAXBLOCK_SHIFT 14
|
||||||
#define EM4x05_FIRST_USER_BLOCK 5
|
#define EM4x05_FIRST_USER_BLOCK 5
|
||||||
#define EM4x05_SET_NUM_BLOCKS(x) ((x+5-1)<<14) //# of blocks sent during default read mode
|
#define EM4x05_SET_NUM_BLOCKS(x) ((x+5-1)<<14) //# of blocks sent during default read mode
|
||||||
#define EM4x05_GET_NUM_BLOCKS(x) (((x>>14) & 0xF)-5+1)
|
#define EM4x05_GET_NUM_BLOCKS(x) (((x>>14) & 0xF)-5+1)
|
||||||
#define EM4x05_READ_LOGIN_REQ 1<<18
|
#define EM4x05_READ_LOGIN_REQ 1<<18
|
||||||
#define EM4x05_READ_HK_LOGIN_REQ 1<<19
|
#define EM4x05_READ_HK_LOGIN_REQ 1<<19
|
||||||
#define EM4x05_WRITE_LOGIN_REQ 1<<20
|
#define EM4x05_WRITE_LOGIN_REQ 1<<20
|
||||||
#define EM4x05_WRITE_HK_LOGIN_REQ 1<<21
|
#define EM4x05_WRITE_HK_LOGIN_REQ 1<<21
|
||||||
#define EM4x05_READ_AFTER_WRITE 1<<22
|
#define EM4x05_READ_AFTER_WRITE 1<<22
|
||||||
#define EM4x05_DISABLE_ALLOWED 1<<23
|
#define EM4x05_DISABLE_ALLOWED 1<<23
|
||||||
#define EM4x05_READER_TALK_FIRST 1<<24
|
#define EM4x05_READER_TALK_FIRST 1<<24
|
||||||
|
|
||||||
|
|
||||||
// FeliCa protocol
|
// FeliCa protocol
|
||||||
#define FELICA_POLL_REQ 0x00
|
#define FELICA_POLL_REQ 0x00
|
||||||
#define FELICA_POLL_ACK 0x01
|
#define FELICA_POLL_ACK 0x01
|
||||||
|
|
||||||
#define FELICA_REQSRV_REQ 0x02
|
#define FELICA_REQSRV_REQ 0x02
|
||||||
#define FELICA_REQSRV_ACK 0x03
|
#define FELICA_REQSRV_ACK 0x03
|
||||||
|
|
||||||
#define FELICA_REQRESP_REQ 0x04
|
#define FELICA_REQRESP_REQ 0x04
|
||||||
#define FELICA_REQRESP_ACK 0x05
|
#define FELICA_REQRESP_ACK 0x05
|
||||||
|
|
||||||
#define FELICA_RDBLK_REQ 0x06
|
#define FELICA_RDBLK_REQ 0x06
|
||||||
#define FELICA_RDBLK_ACK 0x07
|
#define FELICA_RDBLK_ACK 0x07
|
||||||
|
|
||||||
#define FELICA_WRTBLK_REQ 0x08
|
#define FELICA_WRTBLK_REQ 0x08
|
||||||
#define FELICA_WRTBLK_ACK 0x09
|
#define FELICA_WRTBLK_ACK 0x09
|
||||||
|
|
||||||
#define FELICA_SRCHSYSCODE_REQ 0x0a
|
#define FELICA_SRCHSYSCODE_REQ 0x0a
|
||||||
#define FELICA_SRCHSYSCODE_ACK 0x0b
|
#define FELICA_SRCHSYSCODE_ACK 0x0b
|
||||||
|
|
||||||
#define FELICA_REQSYSCODE_REQ 0x0c
|
#define FELICA_REQSYSCODE_REQ 0x0c
|
||||||
#define FELICA_REQSYSCODE_ACK 0x0d
|
#define FELICA_REQSYSCODE_ACK 0x0d
|
||||||
|
|
||||||
#define FELICA_AUTH1_REQ 0x10
|
#define FELICA_AUTH1_REQ 0x10
|
||||||
#define FELICA_AUTH1_ACK 0x11
|
#define FELICA_AUTH1_ACK 0x11
|
||||||
|
|
||||||
#define FELICA_AUTH2_REQ 0x12
|
#define FELICA_AUTH2_REQ 0x12
|
||||||
#define FELICA_AUTH2_ACK 0x13
|
#define FELICA_AUTH2_ACK 0x13
|
||||||
|
|
||||||
#define FELICA_RDSEC_REQ 0x14
|
#define FELICA_RDSEC_REQ 0x14
|
||||||
#define FELICA_RDSEC_ACK 0x15
|
#define FELICA_RDSEC_ACK 0x15
|
||||||
|
|
||||||
#define FELICA_WRTSEC_REQ 0x16
|
#define FELICA_WRTSEC_REQ 0x16
|
||||||
#define FELICA_WRTSEC_ACK 0x17
|
#define FELICA_WRTSEC_ACK 0x17
|
||||||
|
|
||||||
#define FELICA_REQSRV2_REQ 0x32
|
#define FELICA_REQSRV2_REQ 0x32
|
||||||
#define FELICA_REQSRV2_ACK 0x33
|
#define FELICA_REQSRV2_ACK 0x33
|
||||||
|
|
||||||
#define FELICA_GETSTATUS_REQ 0x38
|
#define FELICA_GETSTATUS_REQ 0x38
|
||||||
#define FELICA_GETSTATUS_ACK 0x39
|
#define FELICA_GETSTATUS_ACK 0x39
|
||||||
|
|
||||||
#define FELICA_OSVER_REQ 0x3c
|
#define FELICA_OSVER_REQ 0x3c
|
||||||
#define FELICA_OSVER_ACK 0x3d
|
#define FELICA_OSVER_ACK 0x3d
|
||||||
|
|
||||||
#define FELICA_RESET_MODE_REQ 0x3e
|
#define FELICA_RESET_MODE_REQ 0x3e
|
||||||
#define FELICA_RESET_MODE_ACK 0x3f
|
#define FELICA_RESET_MODE_ACK 0x3f
|
||||||
|
|
||||||
#define FELICA_AUTH1V2_REQ 0x40
|
#define FELICA_AUTH1V2_REQ 0x40
|
||||||
#define FELICA_AUTH1V2_ACK 0x41
|
#define FELICA_AUTH1V2_ACK 0x41
|
||||||
|
|
||||||
#define FELICA_AUTH2V2_REQ 0x42
|
#define FELICA_AUTH2V2_REQ 0x42
|
||||||
#define FELICA_AUTH2V2_ACK 0x43
|
#define FELICA_AUTH2V2_ACK 0x43
|
||||||
|
|
||||||
#define FELICA_RDSECV2_REQ 0x44
|
#define FELICA_RDSECV2_REQ 0x44
|
||||||
#define FELICA_RDSECV2_ACK 0x45
|
#define FELICA_RDSECV2_ACK 0x45
|
||||||
#define FELICA_WRTSECV2_REQ 0x46
|
#define FELICA_WRTSECV2_REQ 0x46
|
||||||
#define FELICA_WRTSECV2_ACK 0x47
|
#define FELICA_WRTSECV2_ACK 0x47
|
||||||
|
|
||||||
#define FELICA_UPDATE_RNDID_REQ 0x4C
|
#define FELICA_UPDATE_RNDID_REQ 0x4C
|
||||||
#define FELICA_UPDATE_RNDID_ACK 0x4D
|
#define FELICA_UPDATE_RNDID_ACK 0x4D
|
||||||
|
|
||||||
// FeliCa SYSTEM list
|
// FeliCa SYSTEM list
|
||||||
#define SYSTEMCODE_ANY 0xffff // ANY
|
#define SYSTEMCODE_ANY 0xffff // ANY
|
||||||
#define SYSTEMCODE_FELICA_LITE 0x88b4 // FeliCa Lite
|
#define SYSTEMCODE_FELICA_LITE 0x88b4 // FeliCa Lite
|
||||||
#define SYSTEMCODE_COMMON 0xfe00 // Common
|
#define SYSTEMCODE_COMMON 0xfe00 // Common
|
||||||
#define SYSTEMCODE_EDY 0xfe00 // Edy
|
#define SYSTEMCODE_EDY 0xfe00 // Edy
|
||||||
#define SYSTEMCODE_CYBERNE 0x0003 // Cyberne
|
#define SYSTEMCODE_CYBERNE 0x0003 // Cyberne
|
||||||
#define SYSTEMCODE_SUICA 0x0003 // Suica
|
#define SYSTEMCODE_SUICA 0x0003 // Suica
|
||||||
#define SYSTEMCODE_PASMO 0x0003 // Pasmo
|
#define SYSTEMCODE_PASMO 0x0003 // Pasmo
|
||||||
|
|
||||||
//FeliCa Service list Suica/pasmo (little endian)
|
//FeliCa Service list Suica/pasmo (little endian)
|
||||||
#define SERVICE_SUICA_INOUT 0x108f // SUICA/PASMO
|
#define SERVICE_SUICA_INOUT 0x108f // SUICA/PASMO
|
||||||
#define SERVICE_SUICA_HISTORY 0x090f // SUICA/PASMO
|
#define SERVICE_SUICA_HISTORY 0x090f // SUICA/PASMO
|
||||||
#define SERVICE_FELICA_LITE_READONLY 0x0b00 // FeliCa Lite RO
|
#define SERVICE_FELICA_LITE_READONLY 0x0b00 // FeliCa Lite RO
|
||||||
#define SERVICE_FELICA_LITE_READWRITE 0x0900 // FeliCa Lite RW
|
#define SERVICE_FELICA_LITE_READWRITE 0x0900 // FeliCa Lite RW
|
||||||
|
|
||||||
// Calypso protocol
|
// Calypso protocol
|
||||||
#define CALYPSO_GET_RESPONSE 0xC0
|
#define CALYPSO_GET_RESPONSE 0xC0
|
||||||
#define CALYPSO_SELECT 0xA4
|
#define CALYPSO_SELECT 0xA4
|
||||||
#define CALYPSO_INVALIDATE 0x04
|
#define CALYPSO_INVALIDATE 0x04
|
||||||
#define CALYPSO_REHABILITATE 0x44
|
#define CALYPSO_REHABILITATE 0x44
|
||||||
#define CALYPSO_APPEND_RECORD 0xE2
|
#define CALYPSO_APPEND_RECORD 0xE2
|
||||||
#define CALYPSO_DECREASE 0x30
|
#define CALYPSO_DECREASE 0x30
|
||||||
#define CALYPSO_INCREASE 0x32
|
#define CALYPSO_INCREASE 0x32
|
||||||
#define CALYPSO_READ_BINARY 0xB0
|
#define CALYPSO_READ_BINARY 0xB0
|
||||||
#define CALYPSO_READ_RECORD 0xB2
|
#define CALYPSO_READ_RECORD 0xB2
|
||||||
#define CALYPSO_UPDATE_BINARY 0xD6
|
#define CALYPSO_UPDATE_BINARY 0xD6
|
||||||
#define CALYPSO_UPDATE_RECORD 0xDC
|
#define CALYPSO_UPDATE_RECORD 0xDC
|
||||||
#define CALYPSO_WRITE_RECORD 0xD2
|
#define CALYPSO_WRITE_RECORD 0xD2
|
||||||
#define CALYPSO_OPEN_SESSION 0x8A
|
#define CALYPSO_OPEN_SESSION 0x8A
|
||||||
#define CALYPSO_CLOSE_SESSION 0x8E
|
#define CALYPSO_CLOSE_SESSION 0x8E
|
||||||
#define CALYPSO_GET_CHALLENGE 0x84
|
#define CALYPSO_GET_CHALLENGE 0x84
|
||||||
#define CALYPSO_CHANGE_PIN 0xD8
|
#define CALYPSO_CHANGE_PIN 0xD8
|
||||||
#define CALYPSO_VERIFY_PIN 0x20
|
#define CALYPSO_VERIFY_PIN 0x20
|
||||||
#define CALYPSO_SV_GET 0x7C
|
#define CALYPSO_SV_GET 0x7C
|
||||||
#define CALYPSO_SV_DEBIT 0xBA
|
#define CALYPSO_SV_DEBIT 0xBA
|
||||||
#define CALYPSO_SV_RELOAD 0xB8
|
#define CALYPSO_SV_RELOAD 0xB8
|
||||||
#define CALYPSO_SV_UN_DEBIT 0xBC
|
#define CALYPSO_SV_UN_DEBIT 0xBC
|
||||||
#define CALYPSO_SAM_SV_DEBIT 0x54
|
#define CALYPSO_SAM_SV_DEBIT 0x54
|
||||||
#define CALYPSO_SAM_SV_RELOAD 0x56
|
#define CALYPSO_SAM_SV_RELOAD 0x56
|
||||||
|
|
||||||
// iclass / picopass chip config structures and shared routines
|
// iclass / picopass chip config structures and shared routines
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t app_limit; //[8]
|
uint8_t app_limit; //[8]
|
||||||
uint8_t otp[2]; //[9-10]
|
uint8_t otp[2]; //[9-10]
|
||||||
uint8_t block_writelock;//[11]
|
uint8_t block_writelock;//[11]
|
||||||
uint8_t chip_config; //[12]
|
uint8_t chip_config; //[12]
|
||||||
uint8_t mem_config; //[13]
|
uint8_t mem_config; //[13]
|
||||||
uint8_t eas; //[14]
|
uint8_t eas; //[14]
|
||||||
uint8_t fuses; //[15]
|
uint8_t fuses; //[15]
|
||||||
} picopass_conf_block;
|
} picopass_conf_block;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t csn[8];
|
uint8_t csn[8];
|
||||||
picopass_conf_block conf;
|
picopass_conf_block conf;
|
||||||
uint8_t epurse[8];
|
uint8_t epurse[8];
|
||||||
uint8_t key_d[8];
|
uint8_t key_d[8];
|
||||||
uint8_t key_c[8];
|
uint8_t key_c[8];
|
||||||
uint8_t app_issuer_area[8];
|
uint8_t app_issuer_area[8];
|
||||||
} picopass_hdr;
|
} picopass_hdr;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,17 @@ static uint32_t g_nextrandom;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline void fast_prand(){
|
inline void fast_prand(){
|
||||||
fast_prandEx(GetTickCount());
|
fast_prandEx(GetTickCount());
|
||||||
}
|
}
|
||||||
inline void fast_prandEx(uint32_t seed) {
|
inline void fast_prandEx(uint32_t seed) {
|
||||||
g_nextrandom = seed;
|
g_nextrandom = seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t prand() {
|
uint32_t prand() {
|
||||||
// g_nextrandom *= 6364136223846793005;
|
// g_nextrandom *= 6364136223846793005;
|
||||||
// g_nextrandom += 1;
|
// g_nextrandom += 1;
|
||||||
//return (uint32_t)(g_nextrandom >> 32) % 0xffffffff;
|
//return (uint32_t)(g_nextrandom >> 32) % 0xffffffff;
|
||||||
g_nextrandom = (214013 * g_nextrandom + 2531011);
|
g_nextrandom = (214013 * g_nextrandom + 2531011);
|
||||||
return (g_nextrandom>>16) & 0xFFFF;
|
return (g_nextrandom>>16) & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
74
common/tea.c
74
common/tea.c
|
@ -13,52 +13,52 @@
|
||||||
|
|
||||||
void tea_encrypt(uint8_t *v, uint8_t *key) {
|
void tea_encrypt(uint8_t *v, uint8_t *key) {
|
||||||
|
|
||||||
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
|
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
uint8_t n = ROUNDS;
|
uint8_t n = ROUNDS;
|
||||||
|
|
||||||
//key
|
//key
|
||||||
a = bytes_to_num(key, 4);
|
a = bytes_to_num(key, 4);
|
||||||
b = bytes_to_num(key+4, 4);
|
b = bytes_to_num(key+4, 4);
|
||||||
c = bytes_to_num(key+8, 4);
|
c = bytes_to_num(key+8, 4);
|
||||||
d = bytes_to_num(key+12, 4);
|
d = bytes_to_num(key+12, 4);
|
||||||
|
|
||||||
//input
|
//input
|
||||||
y = bytes_to_num(v, 4);
|
y = bytes_to_num(v, 4);
|
||||||
z = bytes_to_num(v+4, 4);
|
z = bytes_to_num(v+4, 4);
|
||||||
|
|
||||||
while ( n-- > 0 ) {
|
while ( n-- > 0 ) {
|
||||||
sum += DELTA;
|
sum += DELTA;
|
||||||
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
||||||
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_to_bytes(y, 4, v);
|
num_to_bytes(y, 4, v);
|
||||||
num_to_bytes(z, 4, v+4);
|
num_to_bytes(z, 4, v+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tea_decrypt(uint8_t *v, uint8_t *key) {
|
void tea_decrypt(uint8_t *v, uint8_t *key) {
|
||||||
|
|
||||||
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
|
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
|
||||||
uint32_t sum = SUM;
|
uint32_t sum = SUM;
|
||||||
uint8_t n = ROUNDS;
|
uint8_t n = ROUNDS;
|
||||||
|
|
||||||
//key
|
//key
|
||||||
a = bytes_to_num(key, 4);
|
a = bytes_to_num(key, 4);
|
||||||
b = bytes_to_num(key+4, 4);
|
b = bytes_to_num(key+4, 4);
|
||||||
c = bytes_to_num(key+8, 4);
|
c = bytes_to_num(key+8, 4);
|
||||||
d = bytes_to_num(key+12, 4);
|
d = bytes_to_num(key+12, 4);
|
||||||
|
|
||||||
//input
|
//input
|
||||||
y = bytes_to_num(v, 4);
|
y = bytes_to_num(v, 4);
|
||||||
z = bytes_to_num(v+4, 4);
|
z = bytes_to_num(v+4, 4);
|
||||||
|
|
||||||
/* sum = delta<<5, in general sum = delta * n */
|
/* sum = delta<<5, in general sum = delta * n */
|
||||||
while ( n-- > 0 ) {
|
while ( n-- > 0 ) {
|
||||||
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
|
||||||
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
|
||||||
sum -= DELTA;
|
sum -= DELTA;
|
||||||
}
|
}
|
||||||
num_to_bytes(y, 4, v);
|
num_to_bytes(y, 4, v);
|
||||||
num_to_bytes(z, 4, v+4);
|
num_to_bytes(z, 4, v+4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
#define AT91_BAUD_RATE 115200
|
#define AT91_BAUD_RATE 115200
|
||||||
|
|
||||||
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
||||||
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
|
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
|
||||||
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void usart_close(void) {
|
void usart_close(void) {
|
||||||
// Reset the USART mode
|
// Reset the USART mode
|
||||||
pUS1->US_MR = 0;
|
pUS1->US_MR = 0;
|
||||||
|
|
||||||
// Reset the baud rate divisor register
|
// Reset the baud rate divisor register
|
||||||
pUS1->US_BRGR = 0;
|
pUS1->US_BRGR = 0;
|
||||||
|
|
||||||
// Reset the Timeguard Register
|
// Reset the Timeguard Register
|
||||||
pUS1->US_TTGR = 0;
|
pUS1->US_TTGR = 0;
|
||||||
|
@ -32,7 +32,7 @@ void usart_close(void) {
|
||||||
pUS1->US_IDR = 0xFFFFFFFF;
|
pUS1->US_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
// Abort the Peripheral Data Transfers
|
// Abort the Peripheral Data Transfers
|
||||||
pUS1->US_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
pUS1->US_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||||
|
|
||||||
// Disable receiver and transmitter and stop any activity immediately
|
// Disable receiver and transmitter and stop any activity immediately
|
||||||
pUS1->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
|
pUS1->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
|
||||||
|
@ -46,12 +46,12 @@ static uint8_t us_outbuf[sizeof(UsbCommand)];
|
||||||
/// \param len Size of the data buffer (in bytes).
|
/// \param len Size of the data buffer (in bytes).
|
||||||
inline int16_t usart_readbuffer(uint8_t *data, size_t len) {
|
inline int16_t usart_readbuffer(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
// Check if the first PDC bank is free
|
// Check if the first PDC bank is free
|
||||||
if (!(pUS1->US_RCR)) {
|
if (!(pUS1->US_RCR)) {
|
||||||
pUS1->US_RPR = (uint32_t)data;
|
pUS1->US_RPR = (uint32_t)data;
|
||||||
pUS1->US_RCR = len;
|
pUS1->US_RCR = len;
|
||||||
|
|
||||||
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
|
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
// Check if the second PDC bank is free
|
// Check if the second PDC bank is free
|
||||||
|
@ -59,7 +59,7 @@ inline int16_t usart_readbuffer(uint8_t *data, size_t len) {
|
||||||
pUS1->US_RNPR = (uint32_t)data;
|
pUS1->US_RNPR = (uint32_t)data;
|
||||||
pUS1->US_RNCR = len;
|
pUS1->US_RNCR = len;
|
||||||
|
|
||||||
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
|
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -72,21 +72,21 @@ inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
// Check if the first PDC bank is free
|
// Check if the first PDC bank is free
|
||||||
if (!(pUS1->US_TCR)) {
|
if (!(pUS1->US_TCR)) {
|
||||||
memcpy(us_outbuf, data, len);
|
memcpy(us_outbuf, data, len);
|
||||||
pUS1->US_TPR = (uint32_t)us_outbuf;
|
pUS1->US_TPR = (uint32_t)us_outbuf;
|
||||||
pUS1->US_TCR = sizeof(us_outbuf);
|
pUS1->US_TCR = sizeof(us_outbuf);
|
||||||
|
|
||||||
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
|
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
// Check if the second PDC bank is free
|
// Check if the second PDC bank is free
|
||||||
else if (!(pUS1->US_TNCR)) {
|
else if (!(pUS1->US_TNCR)) {
|
||||||
memcpy(us_outbuf, data, len);
|
memcpy(us_outbuf, data, len);
|
||||||
pUS1->US_TNPR = (uint32_t)us_outbuf;
|
pUS1->US_TNPR = (uint32_t)us_outbuf;
|
||||||
pUS1->US_TNCR = sizeof(us_outbuf);
|
pUS1->US_TNCR = sizeof(us_outbuf);
|
||||||
|
|
||||||
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
|
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -94,21 +94,21 @@ inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
void usart_init(void) {
|
void usart_init(void) {
|
||||||
|
|
||||||
// disable & reset receiver / transmitter for configuration
|
// disable & reset receiver / transmitter for configuration
|
||||||
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS);
|
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS);
|
||||||
|
|
||||||
//enable the USART1 Peripheral clock
|
//enable the USART1 Peripheral clock
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
|
||||||
|
|
||||||
// disable PIO control of receive / transmit pins
|
// disable PIO control of receive / transmit pins
|
||||||
pPIO->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
pPIO->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
|
|
||||||
// enable peripheral mode A on receive / transmit pins
|
// enable peripheral mode A on receive / transmit pins
|
||||||
pPIO->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
pPIO->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
pPIO->PIO_BSR = 0;
|
pPIO->PIO_BSR = 0;
|
||||||
|
|
||||||
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
|
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
|
||||||
pPIO->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
pPIO->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
|
|
||||||
// set mode
|
// set mode
|
||||||
pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode
|
pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode
|
||||||
|
@ -118,26 +118,26 @@ void usart_init(void) {
|
||||||
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
||||||
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
||||||
|
|
||||||
// all interrupts disabled
|
// all interrupts disabled
|
||||||
pUS1->US_IDR = 0xFFFF;
|
pUS1->US_IDR = 0xFFFF;
|
||||||
|
|
||||||
// iceman, setting 115200 doesn't work. Only speed I got to work is 9600.
|
// iceman, setting 115200 doesn't work. Only speed I got to work is 9600.
|
||||||
// something fishy with the AT91SAM7S512 USART.. Or I missed something
|
// something fishy with the AT91SAM7S512 USART.. Or I missed something
|
||||||
// For a nice detailed sample, interrupt driven but still relevant.
|
// For a nice detailed sample, interrupt driven but still relevant.
|
||||||
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
|
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
|
||||||
|
|
||||||
// set baudrate to 115200
|
// set baudrate to 115200
|
||||||
// 115200 * 16 == 1843200
|
// 115200 * 16 == 1843200
|
||||||
//
|
//
|
||||||
//pUS1->US_BRGR = (48UL*1000*1000) / (9600*16);
|
//pUS1->US_BRGR = (48UL*1000*1000) / (9600*16);
|
||||||
pUS1->US_BRGR = 48054841 / (9600 << 4);
|
pUS1->US_BRGR = 48054841 / (9600 << 4);
|
||||||
|
|
||||||
// Write the Timeguard Register
|
// Write the Timeguard Register
|
||||||
pUS1->US_TTGR = 0;
|
pUS1->US_TTGR = 0;
|
||||||
pUS1->US_RTOR = 0;
|
pUS1->US_RTOR = 0;
|
||||||
pUS1->US_FIDI = 0;
|
pUS1->US_FIDI = 0;
|
||||||
pUS1->US_IF = 0;
|
pUS1->US_IF = 0;
|
||||||
|
|
||||||
// re-enable receiver / transmitter
|
// re-enable receiver / transmitter
|
||||||
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
|
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
|
||||||
}
|
}
|
1172
common/usb_cdc.c
1172
common/usb_cdc.c
File diff suppressed because it is too large
Load diff
244
common/wiegand.c
244
common/wiegand.c
|
@ -37,27 +37,27 @@ uint8_t checkParity(uint32_t bits, uint8_t len, uint8_t type);
|
||||||
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
|
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
|
||||||
// Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run)
|
// Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run)
|
||||||
size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) {
|
size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) {
|
||||||
uint32_t parityWd = 0;
|
uint32_t parityWd = 0;
|
||||||
size_t j = 0, bitcount = 0;
|
size_t j = 0, bitcount = 0;
|
||||||
for (int word = 0; word < (bLen); word += pLen){
|
for (int word = 0; word < (bLen); word += pLen){
|
||||||
for (int bit = 0; bit < pLen; ++bit){
|
for (int bit = 0; bit < pLen; ++bit){
|
||||||
parityWd = (parityWd << 1) | bitstream[startIdx+word+bit];
|
parityWd = (parityWd << 1) | bitstream[startIdx+word+bit];
|
||||||
bitstream[j++] = (bitstream[startIdx + word + bit]);
|
bitstream[j++] = (bitstream[startIdx + word + bit]);
|
||||||
}
|
}
|
||||||
j--; // overwrite parity with next data
|
j--; // overwrite parity with next data
|
||||||
// if parity fails then return 0
|
// if parity fails then return 0
|
||||||
switch (pType) {
|
switch (pType) {
|
||||||
case 3: if (bitstream[j] == 1) return 0; break; //should be 0 spacer bit
|
case 3: if (bitstream[j] == 1) return 0; break; //should be 0 spacer bit
|
||||||
case 2: if (bitstream[j] == 0) return 0; break; //should be 1 spacer bit
|
case 2: if (bitstream[j] == 0) return 0; break; //should be 1 spacer bit
|
||||||
default: //test parity
|
default: //test parity
|
||||||
if (parityTest(parityWd, pLen, pType) == 0) return 0; break;
|
if (parityTest(parityWd, pLen, pType) == 0) return 0; break;
|
||||||
}
|
}
|
||||||
bitcount += ( pLen - 1 );
|
bitcount += ( pLen - 1 );
|
||||||
parityWd = 0;
|
parityWd = 0;
|
||||||
}
|
}
|
||||||
// if we got here then all the parities passed
|
// if we got here then all the parities passed
|
||||||
//return ID start index and size
|
//return ID start index and size
|
||||||
return bitcount;
|
return bitcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,28 +76,28 @@ size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t p
|
||||||
*/
|
*/
|
||||||
size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType)
|
size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType)
|
||||||
{
|
{
|
||||||
uint32_t parityWd = 0;
|
uint32_t parityWd = 0;
|
||||||
size_t j = 0, bitCnt = 0;
|
size_t j = 0, bitCnt = 0;
|
||||||
for (int word = 0; word < sourceLen; word += pLen-1) {
|
for (int word = 0; word < sourceLen; word += pLen-1) {
|
||||||
for (int bit = 0; bit < pLen-1; ++bit){
|
for (int bit = 0; bit < pLen-1; ++bit){
|
||||||
parityWd = (parityWd << 1) | bits[word+bit];
|
parityWd = (parityWd << 1) | bits[word+bit];
|
||||||
dest[j++] = (bits[word+bit]);
|
dest[j++] = (bits[word+bit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if parity fails then return 0
|
// if parity fails then return 0
|
||||||
switch (pType) {
|
switch (pType) {
|
||||||
case 3: dest[j++] = 0; break; // marker bit which should be a 0
|
case 3: dest[j++] = 0; break; // marker bit which should be a 0
|
||||||
case 2: dest[j++] = 1; break; // marker bit which should be a 1
|
case 2: dest[j++] = 1; break; // marker bit which should be a 1
|
||||||
default:
|
default:
|
||||||
dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1;
|
dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bitCnt += pLen;
|
bitCnt += pLen;
|
||||||
parityWd = 0;
|
parityWd = 0;
|
||||||
}
|
}
|
||||||
// if we got here then all the parities passed
|
// if we got here then all the parities passed
|
||||||
//return ID start index and size
|
//return ID start index and size
|
||||||
return bitCnt;
|
return bitCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
|
@ -110,18 +110,18 @@ size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen,
|
||||||
*/
|
*/
|
||||||
void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) {
|
void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) {
|
||||||
|
|
||||||
// Copy to destination, shifted one step to make room for EVEN parity
|
// Copy to destination, shifted one step to make room for EVEN parity
|
||||||
memcpy(dest+1, source, length);
|
memcpy(dest+1, source, length);
|
||||||
|
|
||||||
// half length, Even and Odd is calculated to the middle.
|
// half length, Even and Odd is calculated to the middle.
|
||||||
uint8_t len_h2 = length >> 1;
|
uint8_t len_h2 = length >> 1;
|
||||||
|
|
||||||
// add EVEN parity at the beginning
|
// add EVEN parity at the beginning
|
||||||
*(dest) = GetParity(source, EVEN, len_h2);
|
*(dest) = GetParity(source, EVEN, len_h2);
|
||||||
|
|
||||||
dest += length + 1;
|
dest += length + 1;
|
||||||
|
|
||||||
// add ODD parity at the very end
|
// add ODD parity at the very end
|
||||||
*(dest) = GetParity(source + len_h2, ODD, len_h2);
|
*(dest) = GetParity(source + len_h2, ODD, len_h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,18 +138,18 @@ void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) {
|
||||||
*/
|
*/
|
||||||
void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
|
void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
|
||||||
|
|
||||||
uint8_t data[MAX_BITS_TXX55] = {0};
|
uint8_t data[MAX_BITS_TXX55] = {0};
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
|
|
||||||
num_to_wiegand_bits(oem, fc, cn, data, formatlen);
|
num_to_wiegand_bits(oem, fc, cn, data, formatlen);
|
||||||
|
|
||||||
// loop
|
// loop
|
||||||
// (formatlen / 32 ) + 1
|
// (formatlen / 32 ) + 1
|
||||||
// (formatlen >> 5) + 1
|
// (formatlen >> 5) + 1
|
||||||
for (int i = 0; i < formatlen ; ++i){
|
for (int i = 0; i < formatlen ; ++i){
|
||||||
uint32_t value = bytebits_to_byte( data + (i * 32), 32);
|
uint32_t value = bytebits_to_byte( data + (i * 32), 32);
|
||||||
num_to_bytes(value, 32, dest + (i*4) );
|
num_to_bytes(value, 32, dest + (i*4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -162,70 +162,70 @@ void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest,
|
||||||
*/
|
*/
|
||||||
void num_to_wiegand_bits(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
|
void num_to_wiegand_bits(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
|
||||||
|
|
||||||
uint8_t bits[MAX_BITS_TXX55] = {0};
|
uint8_t bits[MAX_BITS_TXX55] = {0};
|
||||||
memset(bits, 0, sizeof(bits));
|
memset(bits, 0, sizeof(bits));
|
||||||
uint8_t *temp = bits;
|
uint8_t *temp = bits;
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
switch ( formatlen ){
|
switch ( formatlen ){
|
||||||
case 26 : // 26bit HID H10301
|
case 26 : // 26bit HID H10301
|
||||||
fc &= 0xFF; // 8bits
|
fc &= 0xFF; // 8bits
|
||||||
cn &= 0xFFFF; // 16bits
|
cn &= 0xFFFF; // 16bits
|
||||||
value = fc << 16 | cn;
|
value = fc << 16 | cn;
|
||||||
num_to_bytebits(value, 24, temp);
|
num_to_bytebits(value, 24, temp);
|
||||||
wiegand_add_parity(temp, dest, 24);
|
wiegand_add_parity(temp, dest, 24);
|
||||||
break;
|
break;
|
||||||
case 261: // 26bit Indala
|
case 261: // 26bit Indala
|
||||||
fc &= 0xFFF; // 12bits
|
fc &= 0xFFF; // 12bits
|
||||||
cn &= 0xFFF; // 12bits
|
cn &= 0xFFF; // 12bits
|
||||||
value = fc << 12 | cn;
|
value = fc << 12 | cn;
|
||||||
num_to_bytebits(value, 24, temp);
|
num_to_bytebits(value, 24, temp);
|
||||||
wiegand_add_parity(temp, dest, 24);
|
wiegand_add_parity(temp, dest, 24);
|
||||||
break;
|
break;
|
||||||
case 34 : // 34bits HID
|
case 34 : // 34bits HID
|
||||||
fc &= 0xFFFF; // 16bits
|
fc &= 0xFFFF; // 16bits
|
||||||
cn &= 0xFFFF; // 16bits
|
cn &= 0xFFFF; // 16bits
|
||||||
value = fc << 16 | cn;
|
value = fc << 16 | cn;
|
||||||
num_to_bytebits(value, 32, temp);
|
num_to_bytebits(value, 32, temp);
|
||||||
wiegand_add_parity(temp, dest, 32);
|
wiegand_add_parity(temp, dest, 32);
|
||||||
break;
|
break;
|
||||||
case 35 : // 35bits HID
|
case 35 : // 35bits HID
|
||||||
fc &= 0xFFF; // 12bits
|
fc &= 0xFFF; // 12bits
|
||||||
cn &= 0xFFFFFF; // 20bits
|
cn &= 0xFFFFFF; // 20bits
|
||||||
value = fc << 20 | cn;
|
value = fc << 20 | cn;
|
||||||
num_to_bytebits(value, 32, temp);
|
num_to_bytebits(value, 32, temp);
|
||||||
wiegand_add_parity(temp, dest, 32);
|
wiegand_add_parity(temp, dest, 32);
|
||||||
break;
|
break;
|
||||||
case 37 : // H10304
|
case 37 : // H10304
|
||||||
fc &= 0xFFFF; // 16bits
|
fc &= 0xFFFF; // 16bits
|
||||||
cn &= 0x7FFFF; // 19bits
|
cn &= 0x7FFFF; // 19bits
|
||||||
value = fc << 19 | cn;
|
value = fc << 19 | cn;
|
||||||
num_to_bytebits(value, 35, temp);
|
num_to_bytebits(value, 35, temp);
|
||||||
wiegand_add_parity(temp, dest, 35);
|
wiegand_add_parity(temp, dest, 35);
|
||||||
break;
|
break;
|
||||||
case 39 : // 39bit KERI System Pyramid
|
case 39 : // 39bit KERI System Pyramid
|
||||||
fc &= 0x1FFFF; // 17bits
|
fc &= 0x1FFFF; // 17bits
|
||||||
cn &= 0xFFFFFFFF; // 20bits
|
cn &= 0xFFFFFFFF; // 20bits
|
||||||
value = fc << 20 | cn;
|
value = fc << 20 | cn;
|
||||||
num_to_bytebits(value, 37, temp);
|
num_to_bytebits(value, 37, temp);
|
||||||
wiegand_add_parity(temp, dest, 37);
|
wiegand_add_parity(temp, dest, 37);
|
||||||
break;
|
break;
|
||||||
case 44 : // 44bit KERI system Pyramid
|
case 44 : // 44bit KERI system Pyramid
|
||||||
oem &= 0xFF; // 8bits
|
oem &= 0xFF; // 8bits
|
||||||
fc &= 0xFFF; // 12bits
|
fc &= 0xFFF; // 12bits
|
||||||
cn &= 0xFFFFFFFF; // 21bits
|
cn &= 0xFFFFFFFF; // 21bits
|
||||||
value = oem << 20 | fc << 12 | cn;
|
value = oem << 20 | fc << 12 | cn;
|
||||||
num_to_bytebits(value, 42, temp);
|
num_to_bytebits(value, 42, temp);
|
||||||
wiegand_add_parity(temp, dest, 42);
|
wiegand_add_parity(temp, dest, 42);
|
||||||
break;
|
break;
|
||||||
case 50 : // AWID 50 RBH
|
case 50 : // AWID 50 RBH
|
||||||
fc &= 0xFFFF; // 16bits
|
fc &= 0xFFFF; // 16bits
|
||||||
cn &= 0xFFFFFFFF // 32bits
|
cn &= 0xFFFFFFFF // 32bits
|
||||||
value = fc << 32 | cn;
|
value = fc << 32 | cn;
|
||||||
num_to_bytebits(value, 48, temp);
|
num_to_bytebits(value, 48, temp);
|
||||||
wiegand_add_parity(temp, dest, 48); // verify!
|
wiegand_add_parity(temp, dest, 48); // verify!
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue