common: fix mix of spaces & tabs

This commit is contained in:
Philippe Teuwen 2019-03-09 19:19:50 +01:00
parent 9502b54aa0
commit 23f1a253a7
32 changed files with 4323 additions and 4323 deletions

View file

@ -1,47 +1,47 @@
#include "bucketsort.h"
extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
uint32_t* const ostart, uint32_t* const ostop,
bucket_info_t *bucket_info, bucket_array_t bucket)
uint32_t* const ostart, uint32_t* const ostop,
bucket_info_t *bucket_info, bucket_array_t bucket)
{
uint32_t *p1, *p2;
uint32_t *start[2];
uint32_t *stop[2];
uint32_t *p1, *p2;
uint32_t *start[2];
uint32_t *stop[2];
start[0] = estart;
stop[0] = estop;
start[1] = ostart;
stop[1] = ostop;
start[0] = estart;
stop[0] = estop;
start[1] = ostart;
stop[1] = ostop;
// init buckets to be empty
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0x00; j <= 0xff; j++) {
bucket[i][j].bp = bucket[i][j].head;
}
}
// init buckets to be empty
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0x00; j <= 0xff; j++) {
bucket[i][j].bp = bucket[i][j].head;
}
}
// sort the lists into the buckets based on the MSB (contribution bits)
for (uint32_t i = 0; i < 2; i++) {
for (p1 = start[i]; p1 <= stop[i]; p1++) {
uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
*(bucket[i][bucket_index].bp++) = *p1;
}
}
// sort the lists into the buckets based on the MSB (contribution bits)
for (uint32_t i = 0; i < 2; i++) {
for (p1 = start[i]; p1 <= stop[i]; p1++) {
uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
*(bucket[i][bucket_index].bp++) = *p1;
}
}
// 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.
uint32_t nonempty_bucket;
for (uint32_t i = 0; i < 2; i++) {
p1 = start[i];
nonempty_bucket = 0;
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
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
nonempty_bucket++;
}
}
bucket_info->numbuckets = nonempty_bucket;
}
// 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.
uint32_t nonempty_bucket;
for (uint32_t i = 0; i < 2; i++) {
p1 = start[i];
nonempty_bucket = 0;
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
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
nonempty_bucket++;
}
}
bucket_info->numbuckets = nonempty_bucket;
}
}

View file

@ -5,20 +5,20 @@
#include <stdlib.h>
typedef struct bucket {
uint32_t *head;
uint32_t *bp;
uint32_t *head;
uint32_t *bp;
} bucket_t;
typedef bucket_t bucket_array_t[2][0x100];
typedef struct bucket_info {
struct {
uint32_t *head, *tail;
} bucket_info[2][0x100];
uint32_t numbuckets;
struct {
uint32_t *head, *tail;
} bucket_info[2][0x100];
uint32_t numbuckets;
} bucket_info_t;
void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
uint32_t* const ostart, uint32_t* const ostop,
bucket_info_t *bucket_info, bucket_array_t bucket);
uint32_t* const ostart, uint32_t* const ostop,
bucket_info_t *bucket_info, bucket_array_t bucket);
#endif

View file

@ -32,33 +32,33 @@
#include "cmd.h"
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++)
((uint8_t*)&txcmd)[i] = 0x00;
for (size_t i=0; i < sizeof(UsbCommand); i++)
((uint8_t*)&txcmd)[i] = 0x00;
// Compose the outgoing command frame
txcmd.cmd = cmd;
txcmd.arg[0] = arg0;
txcmd.arg[1] = arg1;
txcmd.arg[2] = arg2;
// Compose the outgoing command frame
txcmd.cmd = cmd;
txcmd.arg[0] = arg0;
txcmd.arg[1] = arg1;
txcmd.arg[2] = arg2;
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
if (data && len) {
len = MIN(len, USB_CMD_DATA_SIZE);
for (size_t i=0; i<len; i++) {
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
}
}
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
if (data && len) {
len = MIN(len, USB_CMD_DATA_SIZE);
for (size_t i=0; i<len; i++) {
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
}
}
uint32_t sendlen = 0;
// Send frame and make sure all bytes are transmitted
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
uint32_t sendlen = 0;
// Send frame and make sure all bytes are transmitted
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
#ifdef WITH_FPC
// usart_init();
// usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
// usart_init();
// usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
#endif
return sendlen;
return sendlen;
}

View file

@ -1,19 +1,19 @@
/* crapto1.c
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, US$
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, US$
Copyright (C) 2008-2014 bla <blapost@gmail.com>
*/
@ -26,9 +26,9 @@
static uint8_t filterlut[1 << 20];
static void __attribute__((constructor)) fill_lut()
{
uint32_t i;
for(i = 0; i < 1 << 20; ++i)
filterlut[i] = filter(i);
uint32_t i;
for(i = 0; i < 1 << 20; ++i)
filterlut[i] = filter(i);
}
#define filter(x) (filterlut[(x) & 0xfffff])
#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)
{
uint32_t p = *item >> 25;
uint32_t p = *item >> 25;
p = p << 1 | evenparity32(*item & mask1);
p = p << 1 | evenparity32(*item & mask2);
*item = p << 24 | (*item & 0xffffff);
p = p << 1 | evenparity32(*item & mask1);
p = p << 1 | evenparity32(*item & mask2);
*item = p << 24 | (*item & 0xffffff);
}
/** 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)
{
in <<= 24;
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
if(filter(*tbl) ^ filter(*tbl | 1)) {
*tbl |= filter(*tbl) ^ bit;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else if(filter(*tbl) == bit) {
*++*end = tbl[1];
tbl[1] = tbl[0] | 1;
update_contribution(tbl, m1, m2);
*tbl++ ^= in;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else
*tbl-- = *(*end)--;
in <<= 24;
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
if(filter(*tbl) ^ filter(*tbl | 1)) {
*tbl |= filter(*tbl) ^ bit;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else if(filter(*tbl) == bit) {
*++*end = tbl[1];
tbl[1] = tbl[0] | 1;
update_contribution(tbl, m1, m2);
*tbl++ ^= in;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else
*tbl-- = *(*end)--;
}
/** extend_table_simple
* 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)
{
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) {
if(filter(*tbl) ^ filter(*tbl | 1)) { // replace
*tbl |= filter(*tbl) ^ bit;
} else if(filter(*tbl) == bit) { // insert
*++*end = *++tbl;
*tbl = tbl[-1] | 1;
} else { // drop
*tbl-- = *(*end)--;
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) {
if(filter(*tbl) ^ filter(*tbl | 1)) { // replace
*tbl |= filter(*tbl) ^ bit;
} else if(filter(*tbl) == bit) { // insert
*++*end = *++tbl;
*tbl = tbl[-1] | 1;
} else { // drop
*tbl-- = *(*end)--;
}
}
}
}
/** recover
* recursively narrow down the search space, 4 bits of keystream at a time
*/
static struct Crypto1State*
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,
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
{
uint32_t *o, *e;
bucket_info_t bucket_info;
uint32_t *o, *e;
bucket_info_t bucket_info;
if(rem == -1) {
for(e = e_head; e <= e_tail; ++e) {
*e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4);
for(o = o_head; o <= o_tail; ++o, ++sl) {
sl->even = *o;
sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD);
sl[1].odd = sl[1].even = 0;
}
}
return sl;
}
if(rem == -1) {
for(e = e_head; e <= e_tail; ++e) {
*e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4);
for(o = o_head; o <= o_tail; ++o, ++sl) {
sl->even = *o;
sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD);
sl[1].odd = sl[1].even = 0;
}
}
return sl;
}
for(uint32_t i = 0; i < 4 && rem--; i++) {
oks >>= 1;
eks >>= 1;
in >>= 2;
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
if(o_head > o_tail)
return sl;
for(uint32_t i = 0; i < 4 && rem--; i++) {
oks >>= 1;
eks >>= 1;
in >>= 2;
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
if(o_head > o_tail)
return sl;
extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3);
if(e_head > e_tail)
return sl;
}
extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3);
if(e_head > e_tail)
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--) {
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,
rem, sl, in, bucket);
}
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,
bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,
rem, sl, in, bucket);
}
return sl;
return sl;
}
/** lfsr_recovery
* 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 *statelist;
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
int i;
struct Crypto1State *statelist;
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
int i;
// split the keystream into an odd and even part
for (i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i);
for (i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i);
// split the keystream into an odd and even part
for (i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i);
for (i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i);
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
statelist = malloc(sizeof(struct Crypto1State) << 18);
if (!odd_tail-- || !even_tail-- || !statelist) {
free(statelist);
statelist = 0;
goto out;
}
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
statelist = malloc(sizeof(struct Crypto1State) << 18);
if (!odd_tail-- || !even_tail-- || !statelist) {
free(statelist);
statelist = 0;
goto out;
}
statelist->odd = statelist->even = 0;
statelist->odd = statelist->even = 0;
// allocate memory for out of place bucket_sort
bucket_array_t bucket;
// allocate memory for out of place bucket_sort
bucket_array_t bucket;
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0; j <= 0xff; j++) {
bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
if (!bucket[i][j].head) {
goto out;
}
}
}
for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0; j <= 0xff; j++) {
bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
if (!bucket[i][j].head) {
goto out;
}
}
}
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
for(i = 1 << 20; i >= 0; --i) {
if(filter(i) == (oks & 1))
*++odd_tail = i;
if(filter(i) == (eks & 1))
*++even_tail = i;
}
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
for(i = 1 << 20; i >= 0; --i) {
if(filter(i) == (oks & 1))
*++odd_tail = i;
if(filter(i) == (eks & 1))
*++even_tail = i;
}
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
for(i = 0; i < 4; i++) {
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
}
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
for(i = 0; i < 4; i++) {
extend_table_simple(odd_head, &odd_tail, (oks >>= 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.
// 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"
// parameter into account.
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);
// 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"
// parameter into account.
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);
out:
for (uint32_t i = 0; i < 2; i++)
for (uint32_t j = 0; j <= 0xff; j++)
free(bucket[i][j].head);
free(odd_head);
free(even_head);
return statelist;
for (uint32_t i = 0; i < 2; i++)
for (uint32_t j = 0; j <= 0xff; j++)
free(bucket[i][j].head);
free(odd_head);
free(even_head);
return statelist;
}
static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
0x7EC7EE90, 0x7F63F748, 0x79117020};
0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
0x7EC7EE90, 0x7F63F748, 0x79117020};
static const uint32_t T1[] = {
0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
/** 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 *statelist, *sl;
uint8_t oks[32], eks[32], hi[32];
uint32_t low = 0, win = 0;
uint32_t *tail, table[1 << 16];
int i, j;
struct Crypto1State *statelist, *sl;
uint8_t oks[32], eks[32], hi[32];
uint32_t low = 0, win = 0;
uint32_t *tail, table[1 << 16];
int i, j;
sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
if(!sl)
return 0;
sl->odd = sl->even = 0;
sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
if(!sl)
return 0;
sl->odd = sl->even = 0;
for(i = 30; i >= 0; i -= 2) {
oks[i >> 1] = BEBIT(ks2, i);
oks[16 + (i >> 1)] = BEBIT(ks3, i);
}
for(i = 31; i >= 0; i -= 2) {
eks[i >> 1] = BEBIT(ks2, i);
eks[16 + (i >> 1)] = BEBIT(ks3, i);
}
for(i = 30; i >= 0; i -= 2) {
oks[i >> 1] = BEBIT(ks2, i);
oks[16 + (i >> 1)] = BEBIT(ks3, i);
}
for(i = 31; i >= 0; i -= 2) {
eks[i >> 1] = BEBIT(ks2, i);
eks[16 + (i >> 1)] = BEBIT(ks3, i);
}
for(i = 0xfffff; i >= 0; --i) {
if (filter(i) != oks[0])
continue;
for(i = 0xfffff; i >= 0; --i) {
if (filter(i) != oks[0])
continue;
*(tail = table) = i;
for(j = 1; tail >= table && j < 29; ++j)
extend_table_simple(table, &tail, oks[j]);
*(tail = table) = i;
for(j = 1; tail >= table && j < 29; ++j)
extend_table_simple(table, &tail, oks[j]);
if(tail < table)
continue;
if(tail < table)
continue;
for(j = 0; j < 19; ++j)
low = low << 1 | evenparity32(i & S1[j]);
for(j = 0; j < 32; ++j)
hi[j] = evenparity32(i & T1[j]);
for(j = 0; j < 19; ++j)
low = low << 1 | evenparity32(i & S1[j]);
for(j = 0; j < 32; ++j)
hi[j] = evenparity32(i & T1[j]);
for(; tail >= table; --tail) {
for(j = 0; j < 3; ++j) {
*tail = *tail << 1;
*tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j]));
if(filter(*tail) != oks[29 + j])
goto continue2;
}
for(; tail >= table; --tail) {
for(j = 0; j < 3; ++j) {
*tail = *tail << 1;
*tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j]));
if(filter(*tail) != oks[29 + j])
goto continue2;
}
for(j = 0; j < 19; ++j)
win = win << 1 | evenparity32(*tail & S2[j]);
for(j = 0; j < 19; ++j)
win = win << 1 | evenparity32(*tail & S2[j]);
win ^= low;
for(j = 0; j < 32; ++j) {
win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]);
if(filter(win) != eks[j])
goto continue2;
}
win ^= low;
for(j = 0; j < 32; ++j) {
win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]);
if(filter(win) != eks[j])
goto continue2;
}
*tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail);
sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win);
sl->even = win;
++sl;
sl->odd = sl->even = 0;
continue2:;
}
}
return statelist;
*tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail);
sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win);
sl->even = win;
++sl;
sl->odd = sl->even = 0;
continue2:;
}
}
return statelist;
}
/** 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)
{
int out;
uint8_t ret;
uint32_t t;
int out;
uint8_t ret;
uint32_t t;
s->odd &= 0xffffff;
t = s->odd, s->odd = s->even, s->even = t;
s->odd &= 0xffffff;
t = s->odd, s->odd = s->even, s->even = t;
out = s->even & 1;
out ^= LF_POLY_EVEN & (s->even >>= 1);
out ^= LF_POLY_ODD & s->odd;
out ^= !!in;
out ^= (ret = filter(s->odd)) & !!fb;
out = s->even & 1;
out ^= LF_POLY_EVEN & (s->even >>= 1);
out ^= LF_POLY_ODD & s->odd;
out ^= !!in;
out ^= (ret = filter(s->odd)) & !!fb;
s->even |= evenparity32(out) << 23;
return ret;
s->even |= evenparity32(out) << 23;
return ret;
}
/** lfsr_rollback_byte
* 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 ret = 0;
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, 5), fb) << 5;
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, 2), fb) << 2;
ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;
ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;
return ret;
uint8_t ret = 0;
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, 5), fb) << 5;
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, 2), fb) << 2;
ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;
ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;
return ret;
}
/** lfsr_rollback_word
* 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 ret = 0;
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, 29), fb) << (29 ^ 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, 26), fb) << (26 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24);
uint32_t ret = 0;
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, 29), fb) << (29 ^ 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, 26), fb) << (26 ^ 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, 23), fb) << (23 ^ 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, 20), fb) << (20 ^ 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, 17), fb) << (17 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 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, 21), fb) << (21 ^ 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, 18), fb) << (18 ^ 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, 15), fb) << (15 ^ 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, 12), fb) << (12 ^ 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, 9), fb) << (9 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 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, 13), fb) << (13 ^ 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, 10), fb) << (10 ^ 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, 7), fb) << (7 ^ 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, 4), fb) << (4 ^ 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, 1), fb) << (1 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);
return ret;
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, 5), fb) << (5 ^ 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, 2), fb) << (2 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24);
ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);
return ret;
}
/** nonce_distance
@ -376,17 +376,17 @@ uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
static uint16_t *dist = 0;
int nonce_distance(uint32_t from, uint32_t to)
{
uint16_t x, i;
if(!dist) {
dist = calloc(2 << 16, sizeof(uint8_t));
if(!dist)
return -1;
for (x = i = 1; i; ++i) {
dist[(x & 0xff) << 8 | x >> 8] = i;
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
}
}
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
uint16_t x, i;
if(!dist) {
dist = calloc(2 << 16, sizeof(uint8_t));
if(!dist)
return -1;
for (x = i = 1; i; ++i) {
dist[(x & 0xff) << 8 | x >> 8] = i;
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
}
}
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
}
/** validate_prng_nonce
@ -396,14 +396,14 @@ int nonce_distance(uint32_t from, uint32_t to)
* false = hardend prng
*/
bool validate_prng_nonce(uint32_t nonce) {
// init prng table:
nonce_distance(nonce, nonce);
return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16;
// init prng table:
nonce_distance(nonce, nonce);
return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16;
}
static uint32_t fastfwd[2][8] = {
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
/** 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 *candidates = calloc(4 << 10, sizeof(uint8_t));
if (!candidates) return 0;
uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t));
if (!candidates) return 0;
uint32_t c, entry;
int size = 0, i, good;
uint32_t c, entry;
int size = 0, i, good;
for (i = 0; i < 1 << 21; ++i) {
for (c = 0, good = 1; good && c < 8; ++c) {
entry = i ^ fastfwd[isodd][c];
good &= (BIT(ks[c], isodd) == filter(entry >> 1));
good &= (BIT(ks[c], isodd + 2) == filter(entry));
}
if (good)
candidates[size++] = i;
}
for (i = 0; i < 1 << 21; ++i) {
for (c = 0, good = 1; good && c < 8; ++c) {
entry = i ^ fastfwd[isodd][c];
good &= (BIT(ks[c], isodd) == filter(entry >> 1));
good &= (BIT(ks[c], isodd + 2) == filter(entry));
}
if (good)
candidates[size++] = i;
}
candidates[size] = -1;
candidates[size] = -1;
return candidates;
return candidates;
}
/** 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)
{
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) {
sl->odd = odd ^ fastfwd[1][c];
sl->even = even ^ fastfwd[0][c];
for(c = 0; good && c < 8; ++c) {
sl->odd = odd ^ fastfwd[1][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);
ks2 = lfsr_rollback_word(sl, 0, 0);
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
ks3 = lfsr_rollback_bit(sl, 0, 0);
ks2 = lfsr_rollback_word(sl, 0, 0);
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
if (no_par)
break;
if (no_par)
break;
nr = ks1 ^ (prefix | c << 5);
rr = ks2 ^ rresp;
nr = ks1 ^ (prefix | c << 5);
rr = ks2 ^ rresp;
good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
}
good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
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 *statelist, *s;
uint32_t *odd, *even, *o, *e, top;
struct Crypto1State *statelist, *s;
uint32_t *odd, *even, *o, *e, top;
odd = lfsr_prefix_ks(ks, 1);
even = lfsr_prefix_ks(ks, 0);
odd = lfsr_prefix_ks(ks, 1);
even = lfsr_prefix_ks(ks, 0);
s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
if (!s || !odd || !even) {
free(statelist);
statelist = 0;
goto out;
}
s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
if (!s || !odd || !even) {
free(statelist);
statelist = 0;
goto out;
}
for (o = odd; *o + 1; ++o)
for (e = even; *e + 1; ++e)
for (top = 0; top < 64; ++top) {
*o += 1 << 21;
*e += (!(top & 7) + 1) << 21;
s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
}
for (o = odd; *o + 1; ++o)
for (e = even; *e + 1; ++e)
for (top = 0; top < 64; ++top) {
*o += 1 << 21;
*e += (!(top & 7) + 1) << 21;
s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
}
s->odd = s->even = 0;
s->odd = s->even = 0;
out:
free(odd);
free(even);
return statelist;
free(odd);
free(even);
return statelist;
}

View file

@ -28,7 +28,7 @@ extern "C" {
#endif
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);
#else
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);
extern bool validate_prng_nonce(uint32_t nonce);
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
uint32_t __n = 0,__M = 0, N = 0;\
int __i;\
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
for(__i = FSIZE - 1; __i >= 0; __i--)\
if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
break;\
else if(__i)\
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\
else
uint32_t __n = 0,__M = 0, N = 0;\
int __i;\
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
for(__i = FSIZE - 1; __i >= 0; __i--)\
if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
break;\
else if(__i)\
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\
else
#define LF_POLY_ODD (0x29CE5C)
#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)
static inline int filter(uint32_t const x)
{
uint32_t f;
uint32_t f;
f = 0xf22c0 >> (x & 0xf) & 16;
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
return BIT(0xEC57E80A, f);
f = 0xf22c0 >> (x & 0xf) & 16;
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
return BIT(0xEC57E80A, f);
}
#ifdef __cplusplus
}

View file

@ -1,21 +1,21 @@
/* crypto1.c
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US
Copyright (C) 2008-2008 bla <blapost@gmail.com>
Copyright (C) 2008-2008 bla <blapost@gmail.com>
*/
#include "crapto1.h"
@ -23,121 +23,121 @@
#include "parity.h"
#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)
{
int i;
int i;
for(i = 47;s && i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return;
for(i = 47;s && i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return;
}
void crypto1_destroy(struct Crypto1State *state)
{
state->odd = 0;
state->even = 0;
state->odd = 0;
state->even = 0;
}
#else
struct Crypto1State * crypto1_create(uint64_t key)
{
struct Crypto1State *s = malloc(sizeof(*s));
if ( !s ) return NULL;
struct Crypto1State *s = malloc(sizeof(*s));
if ( !s ) return NULL;
s->odd = s->even = 0;
s->odd = s->even = 0;
int i;
for(i = 47; i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return s;
int i;
for(i = 47; i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return s;
}
void crypto1_destroy(struct Crypto1State *state)
{
free(state);
free(state);
}
#endif
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
{
int i;
for(*lfsr = 0, i = 23; i >= 0; --i) {
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
}
int i;
for(*lfsr = 0, i = 23; i >= 0; --i) {
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
}
}
uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
{
uint32_t feedin, t;
uint8_t ret = filter(s->odd);
uint32_t feedin, t;
uint8_t ret = filter(s->odd);
feedin = ret & !!is_encrypted;
feedin ^= !!in;
feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even;
s->even = s->even << 1 | evenparity32(feedin);
feedin = ret & !!is_encrypted;
feedin ^= !!in;
feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even;
s->even = s->even << 1 | evenparity32(feedin);
t = s->odd;
s->odd = s->even;
s->even = t;
t = s->odd;
s->odd = s->even;
s->even = t;
return ret;
return ret;
}
uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
{
uint8_t ret = 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, 2), is_encrypted) << 2;
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, 5), is_encrypted) << 5;
ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6;
ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7;
return ret;
uint8_t ret = 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, 2), is_encrypted) << 2;
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, 5), is_encrypted) << 5;
ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6;
ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7;
return ret;
}
uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
{
uint32_t ret = 0;
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, 2), is_encrypted) << (2 ^ 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, 5), is_encrypted) << (5 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24);
uint32_t ret = 0;
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, 2), is_encrypted) << (2 ^ 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, 5), is_encrypted) << (5 ^ 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, 8), is_encrypted) << (8 ^ 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, 11), is_encrypted) << (11 ^ 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, 14), is_encrypted) << (14 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 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, 10), is_encrypted) << (10 ^ 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, 13), is_encrypted) << (13 ^ 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, 16), is_encrypted) << (16 ^ 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, 19), is_encrypted) << (19 ^ 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, 22), is_encrypted) << (22 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 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, 18), is_encrypted) << (18 ^ 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, 21), is_encrypted) << (21 ^ 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, 24), is_encrypted) << (24 ^ 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, 27), is_encrypted) << (27 ^ 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, 30), is_encrypted) << (30 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24);
return ret;
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, 26), is_encrypted) << (26 ^ 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, 29), is_encrypted) << (29 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24);
ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24);
return ret;
}
/* 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)
{
SWAPENDIAN(x);
while(n--)
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
SWAPENDIAN(x);
while(n--)
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
return SWAPENDIAN(x);
return SWAPENDIAN(x);
}

View file

@ -10,118 +10,118 @@
#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) {
crc_init(crc, order, polynom, initial_value, final_xor);
crc->refin = refin;
crc->refout = refout;
crc_clear(crc);
crc_init(crc, order, polynom, initial_value, final_xor);
crc->refin = refin;
crc->refout = refout;
crc_clear(crc);
}
void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) {
crc->order = order;
crc->topbit = BITMASK( order-1 );
crc->polynom = polynom;
crc->initial_value = initial_value;
crc->final_xor = final_xor;
crc->mask = (1L<<order)-1;
crc->refin = false;
crc->refout = false;
crc_clear(crc);
crc->order = order;
crc->topbit = BITMASK( order-1 );
crc->polynom = polynom;
crc->initial_value = initial_value;
crc->final_xor = final_xor;
crc->mask = (1L<<order)-1;
crc->refin = false;
crc->refout = false;
crc_clear(crc);
}
void crc_clear(crc_t *crc) {
crc->state = crc->initial_value & crc->mask;
if (crc->refin)
crc->state = reflect(crc->state, crc->order);
crc->state = crc->initial_value & crc->mask;
if (crc->refin)
crc->state = reflect(crc->state, crc->order);
}
void crc_update2(crc_t *crc, uint32_t data, int data_width){
if (crc->refin)
data = reflect(data, data_width);
if (crc->refin)
data = reflect(data, data_width);
// Bring the next byte into the remainder.
crc->state ^= data << (crc->order - data_width);
// Bring the next byte into the remainder.
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)
crc->state = (crc->state << 1) ^ crc->polynom;
else
crc->state = (crc->state << 1);
}
if (crc->state & crc->topbit)
crc->state = (crc->state << 1) ^ crc->polynom;
else
crc->state = (crc->state << 1);
}
}
void crc_update(crc_t *crc, uint32_t data, int data_width)
{
if (crc->refin)
data = reflect(data, data_width);
if (crc->refin)
data = reflect(data, data_width);
int i;
for(i=0; i<data_width; i++) {
int oldstate = crc->state;
crc->state = crc->state >> 1;
if( (oldstate^data) & 1 ) {
crc->state ^= crc->polynom;
}
data >>= 1;
}
int i;
for(i=0; i<data_width; i++) {
int oldstate = crc->state;
crc->state = crc->state >> 1;
if( (oldstate^data) & 1 ) {
crc->state ^= crc->polynom;
}
data >>= 1;
}
}
uint32_t crc_finish(crc_t *crc) {
uint32_t val = crc->state;
if (crc->refout)
val = reflect(val, crc->order);
return ( val ^ crc->final_xor ) & crc->mask;
uint32_t val = crc->state;
if (crc->refout)
val = reflect(val, crc->order);
return ( val ^ crc->final_xor ) & crc->mask;
}
/*
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",
crc->order,
crc->polynom,
crc->initial_value,
crc->final_xor,
crc->mask,
crc->topbit,
(crc->refin) ? "TRUE":"FALSE",
(crc->refout) ? "TRUE":"FALSE",
crc->state
);
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->polynom,
crc->initial_value,
crc->final_xor,
crc->mask,
crc->topbit,
(crc->refin) ? "TRUE":"FALSE",
(crc->refout) ? "TRUE":"FALSE",
crc->state
);
}
*/
// 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) {
crc_t crc;
crc_init_ref(&crc, 8, 0x31, 0, 0, true, true);
for ( int i=0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
return crc_finish(&crc);
crc_t crc;
crc_init_ref(&crc, 8, 0x31, 0, 0, true, true);
for ( int i=0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
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"
uint32_t CRC8Mad(uint8_t *buff, size_t size) {
crc_t crc;
crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false);
for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
return crc_finish(&crc);
crc_t crc;
crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false);
for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
return crc_finish(&crc);
}
// 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) {
crc_t crc;
crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true);
crc_update2(&crc, 1, 1); /* CMD_READ */
crc_update2(&crc, cmd[0], 8);
crc_update2(&crc, cmd[1], 8);
return reflect(crc_finish(&crc), 4);
crc_t crc;
crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true);
crc_update2(&crc, 1, 1); /* CMD_READ */
crc_update2(&crc, cmd[0], 8);
crc_update2(&crc, cmd[1], 8);
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"
// the CRC needs to be reversed before returned.
uint32_t CRC8Legic(uint8_t *buff, size_t size) {
crc_t crc;
crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true);
for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
return reflect8(crc_finish(&crc));
crc_t crc;
crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true);
for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8);
return reflect8(crc_finish(&crc));
}

View file

@ -9,19 +9,19 @@
#ifndef __CRC_H
#define __CRC_H
#include "common.h" //stdint, stddef, stdbool
#include "util.h" // reflect, bswap_16
#include "common.h" //stdint, stddef, stdbool
#include "util.h" // reflect, bswap_16
typedef struct crc {
uint32_t state;
int order;
uint32_t polynom;
uint32_t initial_value;
uint32_t final_xor;
uint32_t mask;
int topbit;
bool refin; /* Parameter: Reflect input bytes? */
bool refout; /* Parameter: Reflect output CRC? */
uint32_t state;
int order;
uint32_t polynom;
uint32_t initial_value;
uint32_t final_xor;
uint32_t mask;
int topbit;
bool refin; /* Parameter: Reflect input bytes? */
bool refout; /* Parameter: Reflect output CRC? */
} crc_t;
/* 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 */
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
.state = ((_initial_value) & ((1L<<(_order))-1)), \
.order = (_order), \
.polynom = (_polynom), \
.initial_value = (_initial_value), \
.final_xor = (_final_xor), \
.mask = ((1L<<(_order))-1) \
.refin = false, \
.refout = false \
}
.state = ((_initial_value) & ((1L<<(_order))-1)), \
.order = (_order), \
.polynom = (_polynom), \
.initial_value = (_initial_value), \
.final_xor = (_final_xor), \
.mask = ((1L<<(_order))-1) \
.refin = false, \
.refout = false \
}
#endif /* __CRC_H */

View file

@ -13,125 +13,125 @@ static CrcType_t crc_type = CRC_NONE;
void init_table(CrcType_t ct) {
// same crc algo, and initialised already
if ( ct == crc_type && crc_table_init)
return;
// same crc algo, and initialised already
if ( ct == crc_type && crc_table_init)
return;
// not the same crc algo. reset table.
if ( ct != crc_type)
reset_table();
// not the same crc algo. reset table.
if ( ct != crc_type)
reset_table();
crc_type = ct;
crc_type = ct;
switch (ct) {
case CRC_14443_A:
case CRC_14443_B:
case CRC_15693:
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
default:
crc_table_init = false;
crc_type = CRC_NONE;
break;
}
switch (ct) {
case CRC_14443_A:
case CRC_14443_B:
case CRC_15693:
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
default:
crc_table_init = false;
crc_type = CRC_NONE;
break;
}
}
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++) {
crc = 0;
if (refin)
c = reflect8(i) << 8;
else
c = i << 8;
for (i = 0; i < 256; i++) {
crc = 0;
if (refin)
c = reflect8(i) << 8;
else
c = i << 8;
for (j = 0; j < 8; j++) {
if ( (crc ^ c) & 0x8000 )
crc = ( crc << 1 ) ^ polynomial;
crc = ( crc << 1 ) ^ polynomial;
else
crc = crc << 1;
crc = crc << 1;
c = c << 1;
}
if (refin)
crc = reflect16(crc);
if (refin)
crc = reflect16(crc);
crc_table[i] = crc;
}
crc_table[i] = crc;
}
crc_table_init = true;
}
void reset_table(void) {
memset(crc_table, 0, sizeof(crc_table));
crc_table_init = false;
crc_type = CRC_NONE;
memset(crc_table, 0, sizeof(crc_table));
crc_table_init = false;
crc_type = CRC_NONE;
}
// table lookup LUT solution
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.
// only usable with polynom orders of 8, 16, 24 or 32.
if (n == 0)
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
// only usable with polynom orders of 8, 16, 24 or 32.
if (n == 0)
return (~initval);
uint16_t crc = initval;
uint16_t crc = initval;
if (refin)
crc = reflect16(crc);
if (refin)
crc = reflect16(crc);
if (!refin)
while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ];
else
while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++];
if (!refin)
while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ];
else
while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++];
if (refout^refin)
crc = reflect16(crc);
if (refout^refin)
crc = reflect16(crc);
return crc;
return crc;
}
// bit looped solution TODO REMOVED
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 )
tmp = ( tmp >> 1 ) ^ polynomial;
else
tmp >>= 1;
if ( (tmp ^ v) & 1 )
tmp = ( tmp >> 1 ) ^ polynomial;
else
tmp >>= 1;
v >>= 1;
}
return ((crc >> 8) ^ tmp) & 0xffff;
v >>= 1;
}
return ((crc >> 8) ^ tmp) & 0xffff;
}
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.
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);
uint8_t c;
uint8_t c;
for (uint32_t i = 0; i < length; ++i) {
c = d[i];
if (refin) c = reflect8(c);
c = d[i];
if (refin) c = reflect8(c);
// xor in at msb
// xor in at msb
remainder ^= (c << 8);
// 8 iteration loop
// 8 iteration loop
for (uint8_t j = 8; j; --j) {
if (remainder & 0x8000) {
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)
remainder = reflect16(remainder);
if (refout)
remainder = reflect16(remainder);
return remainder;
}
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
if ( n == 0 ) return;
// can't calc a crc on less than 1 byte
if ( n == 0 ) return;
init_table(ct);
init_table(ct);
uint16_t crc = 0;
switch (ct) {
case CRC_14443_A: crc = crc16_a(d, n); break;
case CRC_14443_B:
case CRC_15693: crc = crc16_x25(d, n); break;
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
//case CRC_LEGIC:
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
default: break;
}
*first = (crc & 0xFF);
uint16_t crc = 0;
switch (ct) {
case CRC_14443_A: crc = crc16_a(d, n); break;
case CRC_14443_B:
case CRC_15693: crc = crc16_x25(d, n); break;
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
//case CRC_LEGIC:
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
default: break;
}
*first = (crc & 0xFF);
*second = ((crc >> 8) & 0xFF);
}
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)
if ( n < 3 ) return 0;
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return 0;
init_table(ct);
switch (ct) {
case CRC_14443_A: return crc16_a(d, n);
case CRC_14443_B:
case CRC_15693: return crc16_x25(d, n);
case CRC_ICLASS: return crc16_iclass(d, n);
case CRC_FELICA: return crc16_xmodem(d, n);
//case CRC_LEGIC:
case CRC_CCITT: return crc16_ccitt(d, n);
case CRC_KERMIT: return crc16_kermit(d, n);
default: break;
}
return 0;
init_table(ct);
switch (ct) {
case CRC_14443_A: return crc16_a(d, n);
case CRC_14443_B:
case CRC_15693: return crc16_x25(d, n);
case CRC_ICLASS: return crc16_iclass(d, n);
case CRC_FELICA: return crc16_xmodem(d, n);
//case CRC_LEGIC:
case CRC_CCITT: return crc16_ccitt(d, n);
case CRC_KERMIT: return crc16_kermit(d, n);
default: break;
}
return 0;
}
// check CRC
// ct crc type
// d buffer with data
// n length (including crc)
// d buffer with data
// n length (including crc)
//
// This function uses the message + crc bytes in order to compare the "residue" afterwards.
// 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
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)
if ( n < 3 ) return false;
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return false;
init_table(ct);
init_table(ct);
switch (ct) {
case CRC_14443_A: return (crc16_a(d, n) == 0);
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_ICLASS: return (crc16_iclass(d, n) == 0);
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
//case CRC_LEGIC:
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
default: break;
}
return false;
switch (ct) {
case CRC_14443_A: return (crc16_a(d, n) == 0);
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_ICLASS: return (crc16_iclass(d, n) == 0);
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
//case CRC_LEGIC:
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
default: break;
}
return 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) {
return crc16_fast(d, n, 0xffff, false, false);
return crc16_fast(d, n, 0xffff, false, false);
}
// FDX-B ISO11784/85) uses KERMIT
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
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
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
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
@ -240,14 +240,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
// ISO/IEC 13239 (formerly ISO/IEC 3309)
// 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 crc = crc16_fast(d, n, 0xffff, true, true);
crc = ~crc;
return crc;
uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
crc = ~crc;
return crc;
}
// CRC-A (14443-3)
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
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
@ -255,12 +255,12 @@ uint16_t crc16_a(uint8_t const *d, size_t n) {
// poly 0x1021 reflected 0x8408
// 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) {
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.
// 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 initial = uidcrc << 8 | uidcrc;
return crc16_fast(d, n, initial, true, true);
uint16_t initial = uidcrc << 8 | uidcrc;
return crc16_fast(d, n, initial, true, true);
}

View file

@ -14,20 +14,20 @@
#define CRC16_POLY_CCITT 0x1021
#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 {
CRC_NONE,
CRC_14443_A,
CRC_14443_B,
CRC_15693,
CRC_ICLASS,
CRC_FELICA,
CRC_LEGIC,
CRC_CCITT,
CRC_KERMIT,
CRC_NONE,
CRC_14443_A,
CRC_14443_B,
CRC_15693,
CRC_ICLASS,
CRC_FELICA,
CRC_LEGIC,
CRC_CCITT,
CRC_KERMIT,
} CrcType_t;
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );

View file

@ -6,7 +6,7 @@
#define CRC64_ECMA_PRESET 0x0000000000000000
const uint64_t crc64_table[] = {
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
0x0000000000000000, 0x42F0E1EBA9EA3693, 0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C, 0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D, 0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
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) {
for (size_t i = 0; i < len; i++) {
uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
*crc = crc64_table[tableIndex] ^ (*crc << 8);
}
for (size_t i = 0; i < len; i++) {
uint8_t tableIndex = (((uint8_t)(*crc >> 56)) ^ data[i]) & 0xff;
*crc = crc64_table[tableIndex] ^ (*crc << 8);
}
}
//suint8_t x = (c & 0xFF00000000000000 ) >> 56;
//suint8_t x = (c & 0xFF00000000000000 ) >> 56;

View file

@ -1,9 +1,9 @@
#include "proxmark3.h"
/* 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 = {
VERSION_INFORMATION_MAGIC,
1, /* version 1 */
0, /* version information not present */
2, /* cleanliness couldn't be determined */
/* Remaining fields: zero */
VERSION_INFORMATION_MAGIC,
1, /* version 1 */
0, /* version information not present */
2, /* cleanliness couldn't be determined */
/* Remaining fields: zero */
};

View file

@ -55,15 +55,15 @@ typedef enum {
enum DESFIRE_AUTH_SCHEME {
AS_LEGACY,
AS_NEW
AS_LEGACY,
AS_NEW
};
enum DESFIRE_CRYPTOALGO {
T_DES = 0x00,
T_3DES = 0x01,
T_3K3DES = 0x02,
T_AES = 0x03
T_DES = 0x00,
T_3DES = 0x01,
T_3K3DES = 0x02,
T_AES = 0x03
};
@ -74,7 +74,7 @@ struct desfire_key {
// DES_key_schedule ks1;
// DES_key_schedule ks2;
// DES_key_schedule ks3;
AesCtx aes_ks;
AesCtx aes_ks;
uint8_t cmac_sk1[24];
uint8_t cmac_sk2[24];
uint8_t aes_version;
@ -89,10 +89,10 @@ struct desfire_tag {
uint8_t last_internal_error;
uint8_t last_pcd_error;
desfirekey_t session_key;
enum DESFIRE_AUTH_SCHEME authentication_scheme;
enum DESFIRE_AUTH_SCHEME authentication_scheme;
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 *crypto_buffer;
size_t crypto_buffer_size;
@ -111,66 +111,66 @@ enum DESFIRE_FILE_TYPES {
};
enum DESFIRE_STATUS {
OPERATION_OK = 0x00,
NO_CHANGES = 0x0c,
OUT_OF_EEPROM_ERROR = 0x0e,
ILLEGAL_COMMAND_CODE = 0x1c,
INTEGRITY_ERROR = 0x1e,
NO_SUCH_KEY = 0x40,
LENGTH_ERROR = 0x7e,
PERMISSION_DENIED = 0x9d,
PARAMETER_ERROR = 0x9e,
APPLICATION_NOT_FOUND = 0xa0,
APPL_INTEGRITY_ERROR = 0xa1,
AUTHENTICATION_ERROR = 0xae,
ADDITIONAL_FRAME = 0xaf,
BOUNDARY_ERROR = 0xbe,
PICC_INTEGRITY_ERROR = 0xc1,
COMMAND_ABORTED = 0xca,
PICC_DISABLED_ERROR = 0xcd,
COUNT_ERROR = 0xce,
DUPLICATE_ERROR = 0xde,
EEPROM_ERROR = 0xee,
FILE_NOT_FOUND = 0xf0,
FILE_INTEGRITY_ERROR = 0xf1
OPERATION_OK = 0x00,
NO_CHANGES = 0x0c,
OUT_OF_EEPROM_ERROR = 0x0e,
ILLEGAL_COMMAND_CODE = 0x1c,
INTEGRITY_ERROR = 0x1e,
NO_SUCH_KEY = 0x40,
LENGTH_ERROR = 0x7e,
PERMISSION_DENIED = 0x9d,
PARAMETER_ERROR = 0x9e,
APPLICATION_NOT_FOUND = 0xa0,
APPL_INTEGRITY_ERROR = 0xa1,
AUTHENTICATION_ERROR = 0xae,
ADDITIONAL_FRAME = 0xaf,
BOUNDARY_ERROR = 0xbe,
PICC_INTEGRITY_ERROR = 0xc1,
COMMAND_ABORTED = 0xca,
PICC_DISABLED_ERROR = 0xcd,
COUNT_ERROR = 0xce,
DUPLICATE_ERROR = 0xde,
EEPROM_ERROR = 0xee,
FILE_NOT_FOUND = 0xf0,
FILE_INTEGRITY_ERROR = 0xf1
};
enum DESFIRE_CMD {
CREATE_APPLICATION = 0xca,
DELETE_APPLICATION = 0xda,
GET_APPLICATION_IDS = 0x6a,
SELECT_APPLICATION = 0x5a,
FORMAT_PICC = 0xfc,
GET_VERSION = 0x60,
READ_DATA = 0xbd,
WRITE_DATA = 0x3d,
GET_VALUE = 0x6c,
CREDIT = 0x0c,
DEBIT = 0xdc,
LIMITED_CREDIT = 0x1c,
WRITE_RECORD = 0x3b,
READ_RECORDS = 0xbb,
CLEAR_RECORD_FILE = 0xeb,
COMMIT_TRANSACTION = 0xc7,
ABORT_TRANSACTION = 0xa7,
GET_FREE_MEMORY = 0x6e,
GET_FILE_IDS = 0x6f,
GET_FILE_SETTINGS = 0xf5,
CHANGE_FILE_SETTINGS = 0x5f,
CREATE_STD_DATA_FILE = 0xcd,
CREATE_BACKUP_DATA_FILE = 0xcb,
CREATE_VALUE_FILE = 0xcc,
CREATE_LINEAR_RECORD_FILE = 0xc1,
CREATE_CYCLIC_RECORD_FILE = 0xc0,
DELETE_FILE = 0xdf,
AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE
AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD
AUTHENTICATE_AES = 0xaa,
CHANGE_KEY_SETTINGS = 0x54,
GET_KEY_SETTINGS = 0x45,
CHANGE_KEY = 0xc4,
GET_KEY_VERSION = 0x64,
AUTHENTICATION_FRAME = 0xAF
CREATE_APPLICATION = 0xca,
DELETE_APPLICATION = 0xda,
GET_APPLICATION_IDS = 0x6a,
SELECT_APPLICATION = 0x5a,
FORMAT_PICC = 0xfc,
GET_VERSION = 0x60,
READ_DATA = 0xbd,
WRITE_DATA = 0x3d,
GET_VALUE = 0x6c,
CREDIT = 0x0c,
DEBIT = 0xdc,
LIMITED_CREDIT = 0x1c,
WRITE_RECORD = 0x3b,
READ_RECORDS = 0xbb,
CLEAR_RECORD_FILE = 0xeb,
COMMIT_TRANSACTION = 0xc7,
ABORT_TRANSACTION = 0xa7,
GET_FREE_MEMORY = 0x6e,
GET_FILE_IDS = 0x6f,
GET_FILE_SETTINGS = 0xf5,
CHANGE_FILE_SETTINGS = 0x5f,
CREATE_STD_DATA_FILE = 0xcd,
CREATE_BACKUP_DATA_FILE = 0xcb,
CREATE_VALUE_FILE = 0xcc,
CREATE_LINEAR_RECORD_FILE = 0xc1,
CREATE_CYCLIC_RECORD_FILE = 0xc0,
DELETE_FILE = 0xdf,
AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE
AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD
AUTHENTICATE_AES = 0xaa,
CHANGE_KEY_SETTINGS = 0x54,
GET_KEY_SETTINGS = 0x45,
CHANGE_KEY = 0xc4,
GET_KEY_VERSION = 0x64,
AUTHENTICATION_FRAME = 0xAF
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -8,16 +8,16 @@
#include "BigBuf.h"
#include "mifare.h"
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
#define I2C_DEVICE_CMD_GENERATE_ATR 0x01
#define I2C_DEVICE_CMD_SEND 0x02
#define I2C_DEVICE_CMD_READ 0x03
#define I2C_DEVICE_CMD_SETBAUD 0x04
#define I2C_DEVICE_CMD_SIM_CLC 0x05
#define I2C_DEVICE_CMD_GETVERSION 0x06
#define I2C_DEVICE_CMD_SEND_T0 0x07
#define I2C_DEVICE_CMD_GENERATE_ATR 0x01
#define I2C_DEVICE_CMD_SEND 0x02
#define I2C_DEVICE_CMD_READ 0x03
#define I2C_DEVICE_CMD_SETBAUD 0x04
#define I2C_DEVICE_CMD_SIM_CLC 0x05
#define I2C_DEVICE_CMD_GETVERSION 0x06
#define I2C_DEVICE_CMD_SEND_T0 0x07
void I2C_recovery(void);

View file

@ -22,7 +22,7 @@ void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
uint8_t b;
uint16_t crc = CrcType;
do {
do {
b = *data++;
UpdateCrc14443(b, &crc);
} 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) {
if (length < 3) return false;
uint8_t b1, b2;
ComputeCrc14443(CrcType, data, length - 2, &b1, &b2);
if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
return true;
return false;
if (length < 3) return false;
uint8_t b1, b2;
ComputeCrc14443(CrcType, data, length - 2, &b1, &b2);
if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
return true;
return false;
}

View file

@ -9,17 +9,17 @@
// returns a string representation of the UID
// 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
// uid[] the UID in transmission order
// return: ptr to string
// target char* buffer, where to put the UID, if NULL a static buffer is returned
// uid[] the UID in transmission order
// return: ptr to string
char* Iso15693sprintUID(char *target, uint8_t *uid) {
static char tempbuf[2*8+1] = {0};
if (target == NULL)
target = tempbuf;
sprintf(target, "%02X %02X %02X %02X %02X %02X %02X %02X",
uid[7], uid[6], uid[5], uid[4],
uid[3], uid[2], uid[1], uid[0]
);
return target;
static char tempbuf[2*8+1] = {0};
if (target == NULL)
target = tempbuf;
sprintf(target, "%02X %02X %02X %02X %02X %02X %02X %02X",
uid[7], uid[6], uid[5], uid[4],
uid[3], uid[2], uid[1], uid[0]
);
return target;
}

View file

@ -17,58 +17,58 @@
#include "crc16.h"
// REQUEST FLAGS
#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_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_NONINVENTORY 0x00
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
#define ISO15_REQ_PROTOCOL_NONEXT 0x00
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
#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_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_NONINVENTORY 0x00
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
#define ISO15_REQ_PROTOCOL_NONEXT 0x00
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
// REQUEST FLAGS when INVENTORY is not set
#define ISO15_REQ_SELECT 0x10 // only selected cards response
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address
#define ISO15_REQ_OPTION 0x40 // Command specific option selector
#define ISO15_REQ_SELECT 0x10 // only selected cards response
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address
#define ISO15_REQ_OPTION 0x40 // Command specific option selector
//REQUEST FLAGS when INVENTORY is set
#define ISO15_REQINV_AFI 0x10 // AFI Field is present
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector
#define ISO15_REQINV_AFI 0x10 // AFI Field is present
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector
//RESPONSE FLAGS
#define ISO15_RES_ERROR 0x01
#define ISO15_RES_EXT 0x08 // Protocol Extention
#define ISO15_RES_ERROR 0x01
#define ISO15_RES_EXT 0x08 // Protocol Extention
// RESPONSE ERROR CODES
#define ISO15_NOERROR 0x00
#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_OPTION 0x03 // Command option not supported
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
#define ISO15_NOERROR 0x00
#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_OPTION 0x03 // Command option not supported
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
// COMMAND CODES
#define ISO15_CMD_INVENTORY 0x01
#define ISO15_CMD_STAYQUIET 0x02
#define ISO15_CMD_READ 0x20
#define ISO15_CMD_WRITE 0x21
#define ISO15_CMD_LOCK 0x22
#define ISO15_CMD_READMULTI 0x23
#define ISO15_CMD_WRITEMULTI 0x24
#define ISO15_CMD_SELECT 0x25
#define ISO15_CMD_RESET 0x26
#define ISO15_CMD_WRITEAFI 0x27
#define ISO15_CMD_LOCKAFI 0x28
#define ISO15_CMD_WRITEDSFID 0x29
#define ISO15_CMD_LOCKDSFID 0x2A
#define ISO15_CMD_SYSINFO 0x2B
#define ISO15_CMD_SECSTATUS 0x2C
#define ISO15_CMD_INVENTORY 0x01
#define ISO15_CMD_STAYQUIET 0x02
#define ISO15_CMD_READ 0x20
#define ISO15_CMD_WRITE 0x21
#define ISO15_CMD_LOCK 0x22
#define ISO15_CMD_READMULTI 0x23
#define ISO15_CMD_WRITEMULTI 0x24
#define ISO15_CMD_SELECT 0x25
#define ISO15_CMD_RESET 0x26
#define ISO15_CMD_WRITEAFI 0x27
#define ISO15_CMD_LOCKAFI 0x28
#define ISO15_CMD_WRITEDSFID 0x29
#define ISO15_CMD_LOCKDSFID 0x2A
#define ISO15_CMD_SYSINFO 0x2B
#define ISO15_CMD_SECSTATUS 0x2C
char* Iso15693sprintUID(char *target, uint8_t *uid);
@ -78,49 +78,49 @@ char* Iso15693sprintUID(char *target, uint8_t *uid);
// 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
// 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
// SOF defined as
// 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
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
};
static const int Iso15693Logic0[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1
};
static const int Iso15693Logic1[] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
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
};
static const int Iso15693Logic0[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1
};
static const int Iso15693Logic1[] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
// EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us
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
};
// EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us
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
};
#endif

View file

@ -11,13 +11,13 @@ ms of the GNU GPL, version 2 or,
/* AT91SAM7S256 has 256k 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 */
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 */
ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
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 */
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 */
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
}
/* Export some information that can be used from within the firmware */

View file

@ -13,9 +13,9 @@
// c keeps track on which step the prng is.
// legic_prng_get_bit() = gets a bit muxed from a and b.
struct lfsr {
uint8_t a;
uint8_t b;
uint32_t c;
uint8_t a;
uint8_t b;
uint32_t c;
} lfsr;
// 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
//
void legic_prng_init(uint8_t iv) {
lfsr.a = iv;
lfsr.b = 0; // hack to get a always 0 keystream
lfsr.c = 0;
if(iv)
lfsr.b = (iv << 1) | 1;
lfsr.a = iv;
lfsr.b = 0; // hack to get a always 0 keystream
lfsr.c = 0;
if(iv)
lfsr.b = (iv << 1) | 1;
}
void legic_prng_forward(int count) {
if (count == 0) return;
if (count == 0) return;
lfsr.c += count;
while(count--) {
// According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
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.c += count;
while(count--) {
// According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
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;
}
}
uint32_t legic_prng_count() {
return lfsr.c;
return lfsr.c;
}
uint8_t legic_prng_get_bit() {
uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) );
return lfsr.b >> idx & 1;
uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) );
return lfsr.b >> idx & 1;
}
uint32_t legic_prng_get_bits(uint8_t len){
uint32_t a = 0;
for(uint8_t i = 0; i < len; ++i) {
a |= legic_prng_get_bit() << i;
legic_prng_forward(1);
}
return a;
uint32_t a = 0;
for(uint8_t i = 0; i < len; ++i) {
a |= legic_prng_get_bit() << i;
legic_prng_forward(1);
}
return a;
}

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
#include <stdlib.h> // for
#include <stdbool.h> // for bool
#include "parity.h" // for parity test
#include "util.h" // for ARRAYLEN
#include "util.h" // for ARRAYLEN
//might not be high enough for noisy environments
#define NOISE_AMPLITUDE_THRESHOLD 10
@ -30,11 +30,11 @@
//generic
typedef struct {
int low;
int high;
int mean;
int amplitude;
bool isnoise;
int low;
int high;
int mean;
int amplitude;
bool isnoise;
} signal_t;
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 void askAmp(uint8_t *bits, size_t size);
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_byteLSBF(uint8_t *src, size_t numbits);
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 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 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);
@ -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 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 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 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 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 void psk2TOpsk1(uint8_t *bits, size_t size);

View file

@ -22,23 +22,23 @@ extern const uint8_t OddByteParity[256];
static inline bool oddparity8(const uint8_t x) {
return OddByteParity[x];
return OddByteParity[x];
}
static inline bool evenparity8(const uint8_t x) {
return !OddByteParity[x];
return !OddByteParity[x];
}
static inline bool evenparity32(uint32_t x)
{
#if !defined __GNUC__
x ^= x >> 16;
x ^= x >> 8;
return evenparity8(x);
x ^= x >> 16;
x ^= x >> 8;
return evenparity8(x);
#else
return __builtin_parity(x);
return __builtin_parity(x);
#endif
}
@ -46,11 +46,11 @@ static inline bool evenparity32(uint32_t x)
static inline bool oddparity32(uint32_t x)
{
#if !defined __GNUC__
x ^= x >> 16;
x ^= x >> 8;
return oddparity8(x);
x ^= x >> 16;
x ^= x >> 8;
return oddparity8(x);
#else
return !__builtin_parity(x);
return !__builtin_parity(x);
#endif
}

View file

@ -17,7 +17,7 @@ uint32_t burtle_get_mod( prng_ctx *x ) {
void burtle_init_mod(prng_ctx *x, uint32_t seed ) {
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) {
(void)burtle_get_mod(x);
}
@ -33,7 +33,7 @@ void burtle_init(prng_ctx *x, uint32_t seed ) {
uint32_t GetSimplePrng( uint32_t seed ){
seed *= 0x19660D;
seed += 0x3C6EF35F;
return seed;
seed *= 0x19660D;
seed += 0x3C6EF35F;
return seed;
}

View file

@ -9,10 +9,10 @@
#include <stdint.h>
#include <stddef.h>
typedef struct prng_ctx {
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} prng_ctx;
//uint32_t burtle_get( prng_ctx *x );

View file

@ -2,17 +2,17 @@
// ATA55xx shared presets & routines
uint32_t GetT55xxClockBit(uint32_t clock) {
switch (clock) {
case 128: return T55x7_BITRATE_RF_128;
case 100: return T55x7_BITRATE_RF_100;
case 64: return T55x7_BITRATE_RF_64;
case 50: return T55x7_BITRATE_RF_50;
case 40: return T55x7_BITRATE_RF_40;
case 32: return T55x7_BITRATE_RF_32;
case 16: return T55x7_BITRATE_RF_16;
case 8: return T55x7_BITRATE_RF_8;
default : return 0;
}
switch (clock) {
case 128: return T55x7_BITRATE_RF_128;
case 100: return T55x7_BITRATE_RF_100;
case 64: return T55x7_BITRATE_RF_64;
case 50: return T55x7_BITRATE_RF_50;
case 40: return T55x7_BITRATE_RF_40;
case 32: return T55x7_BITRATE_RF_32;
case 16: return T55x7_BITRATE_RF_16;
case 8: return T55x7_BITRATE_RF_8;
default : return 0;
}
}
#ifndef ON_DEVICE
@ -20,122 +20,122 @@ uint32_t GetT55xxClockBit(uint32_t clock) {
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
uint8_t isset(uint8_t val, uint8_t mask) {
return (val & mask);
return (val & mask);
}
uint8_t notset(uint8_t val, uint8_t mask){
return !(val & mask);
return !(val & mask);
}
void fuse_config(const picopass_hdr *hdr) {
uint8_t fuses = hdr->conf.fuses;
uint8_t fuses = hdr->conf.fuses;
if (isset(fuses,FUSE_FPERS))
PrintAndLogDevice(SUCCESS, "\tMode: Personalization [Programmable]");
else
PrintAndLogDevice(NORMAL, "\tMode: Application [Locked]");
if (isset(fuses,FUSE_FPERS))
PrintAndLogDevice(SUCCESS, "\tMode: Personalization [Programmable]");
else
PrintAndLogDevice(NORMAL, "\tMode: Application [Locked]");
if (isset(fuses, FUSE_CODING1)) {
PrintAndLogDevice(NORMAL, "\tCoding: RFU");
} else {
if( isset( fuses , FUSE_CODING0))
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693");
else
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443B only");
}
// 1 1
if( isset (fuses,FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Secured page, keys not locked");
// 1 0
if( isset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: Secured page, keys locked");
// 0 1
if( notset (fuses,FUSE_CRYPT1) && isset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Non secured page");
// 0 0
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_CODING1)) {
PrintAndLogDevice(NORMAL, "\tCoding: RFU");
} else {
if( isset( fuses , FUSE_CODING0))
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443-2 B/ISO 15693");
else
PrintAndLogDevice(NORMAL, "\tCoding: ISO 14443B only");
}
// 1 1
if( isset (fuses,FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Secured page, keys not locked");
// 1 0
if( isset (fuses,FUSE_CRYPT1) && notset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(NORMAL, "\tCrypt: Secured page, keys locked");
// 0 1
if( notset (fuses,FUSE_CRYPT1) && isset( fuses, FUSE_CRYPT0 )) PrintAndLogDevice(SUCCESS, "\tCrypt: Non secured page");
// 0 0
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))
PrintAndLogDevice(NORMAL, "\tRA: Read access enabled");
else
PrintAndLogDevice(WARNING, "\tRA: Read access not enabled");
if( isset( fuses, FUSE_RA))
PrintAndLogDevice(NORMAL, "\tRA: Read access enabled");
else
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) {
// mem-bit 5, mem-bit 7, chip-bit 4: defines chip type
uint8_t k16 = isset(mem_cfg, 0x80);
//uint8_t k2 = isset(mem_cfg, 0x08);
uint8_t book = isset(mem_cfg, 0x20);
// mem-bit 5, mem-bit 7, chip-bit 4: defines chip type
uint8_t k16 = isset(mem_cfg, 0x80);
//uint8_t k2 = isset(mem_cfg, 0x08);
uint8_t book = isset(mem_cfg, 0x20);
if(isset(chip_cfg, 0x10) && !k16 && !book) {
*kb = 2;
*app_areas = 2;
*max_blk = 31;
} else if(isset(chip_cfg, 0x10) && k16 && !book) {
*kb = 16;
*app_areas = 2;
*max_blk = 255; //16kb
} else if(notset(chip_cfg, 0x10) && !k16 && !book) {
*kb = 16;
*app_areas = 16;
*max_blk = 255; //16kb
} else if(isset(chip_cfg, 0x10) && k16 && book) {
*kb = 32;
*app_areas = 3;
*max_blk = 255; //16kb
} else if(notset(chip_cfg, 0x10) && !k16 && book) {
*kb = 32;
*app_areas = 17;
*max_blk = 255; //16kb
} else {
*kb = 32;
*app_areas = 2;
*max_blk = 255;
}
if(isset(chip_cfg, 0x10) && !k16 && !book) {
*kb = 2;
*app_areas = 2;
*max_blk = 31;
} else if(isset(chip_cfg, 0x10) && k16 && !book) {
*kb = 16;
*app_areas = 2;
*max_blk = 255; //16kb
} else if(notset(chip_cfg, 0x10) && !k16 && !book) {
*kb = 16;
*app_areas = 16;
*max_blk = 255; //16kb
} else if(isset(chip_cfg, 0x10) && k16 && book) {
*kb = 32;
*app_areas = 3;
*max_blk = 255; //16kb
} else if(notset(chip_cfg, 0x10) && !k16 && book) {
*kb = 32;
*app_areas = 17;
*max_blk = 255; //16kb
} else {
*kb = 32;
*app_areas = 2;
*max_blk = 255;
}
}
void mem_app_config(const picopass_hdr *hdr) {
uint8_t mem = hdr->conf.mem_config;
uint8_t chip = hdr->conf.chip_config;
uint8_t applimit = hdr->conf.app_limit;
uint8_t kb = 2;
uint8_t app_areas = 2;
uint8_t max_blk = 31;
uint8_t mem = hdr->conf.mem_config;
uint8_t chip = hdr->conf.chip_config;
uint8_t applimit = hdr->conf.app_limit;
uint8_t kb = 2;
uint8_t app_areas = 2;
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 (kb == 2 && (applimit > 0x1f) ) applimit = 26;
if (applimit < 6) 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, "\tAA1: blocks 06-%02X", applimit);
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, "\nKeyAccess:");
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, "\tAA2: blocks %02X-%02X", applimit+1, max_blk);
PrintAndLogDevice(NORMAL, "\tOTP: 0x%02X%02X", hdr->conf.otp[1], hdr->conf.otp[0]);
PrintAndLogDevice(NORMAL, "\nKeyAccess:");
uint8_t book = isset(mem, 0x20);
if (book) {
PrintAndLogDevice(NORMAL, "\tRead A - Kd");
PrintAndLogDevice(NORMAL, "\tRead B - Kc");
PrintAndLogDevice(NORMAL, "\tWrite A - Kd");
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
PrintAndLogDevice(NORMAL,"\tCredit - Kc");
} else{
PrintAndLogDevice(NORMAL, "\tRead A - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tRead B - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tWrite A - Kc");
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tCredit - Kc");
}
uint8_t book = isset(mem, 0x20);
if (book) {
PrintAndLogDevice(NORMAL, "\tRead A - Kd");
PrintAndLogDevice(NORMAL, "\tRead B - Kc");
PrintAndLogDevice(NORMAL, "\tWrite A - Kd");
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
PrintAndLogDevice(NORMAL,"\tCredit - Kc");
} else{
PrintAndLogDevice(NORMAL, "\tRead A - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tRead B - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tWrite A - Kc");
PrintAndLogDevice(NORMAL, "\tWrite B - Kc");
PrintAndLogDevice(NORMAL, "\tDebit - Kd or Kc");
PrintAndLogDevice(NORMAL, "\tCredit - Kc");
}
}
void print_picopass_info(const picopass_hdr *hdr) {
fuse_config(hdr);
mem_app_config(hdr);
fuse_config(hdr);
mem_app_config(hdr);
}
void printIclassDumpInfo(uint8_t* iclass_dump) {
print_picopass_info((picopass_hdr *) iclass_dump);
print_picopass_info((picopass_hdr *) iclass_dump);
}
#else
#define PrintAndLogDevice(level, format, ...) { }
#define PrintAndLogDevice(level, format, ...) { }
#endif
//ON_DEVICE

View file

@ -9,115 +9,115 @@
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
/*
ISO14443A (usually NFC tags)
26 (7bits) = REQA
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])
52 (7bits) = WUPA (usage: 52(7bits) - answer: 2bytes ATQA)
93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
95 20 = Anticollision of cascade level2
95 70 = Select of cascade level2
50 00 = Halt (usage: 5000+2bytes ISO14443A-CRC - no answer from card)
26 (7bits) = REQA
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])
52 (7bits) = WUPA (usage: 52(7bits) - answer: 2bytes ATQA)
93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
95 20 = Anticollision of cascade level2
95 70 = Select of cascade level2
50 00 = Halt (usage: 5000+2bytes ISO14443A-CRC - no answer from card)
Mifare
60 = Authenticate with KeyA
61 = Authenticate with KeyB
40 (7bits) = Used to put Chinese Changeable UID cards in special mode (must be followed by 43 (8bits) - answer: 0A)
C0 = Decrement
C1 = Increment
C2 = Restore
B0 = Transfer
60 = Authenticate with KeyA
61 = Authenticate with KeyB
40 (7bits) = Used to put Chinese Changeable UID cards in special mode (must be followed by 43 (8bits) - answer: 0A)
C0 = Decrement
C1 = Increment
C2 = Restore
B0 = Transfer
Ultralight C
A0 = Compatibility Write (to accomodate MIFARE commands)
1A = Step1 Authenticate
AF = Step2 Authenticate
A0 = Compatibility Write (to accomodate MIFARE commands)
1A = Step1 Authenticate
AF = Step2 Authenticate
ISO14443B
05 = REQB
1D = ATTRIB
50 = HALT
05 = REQB
1D = ATTRIB
50 = HALT
BA = PING (reader -> tag)
AB = PONG (tag -> reader)
BA = PING (reader -> tag)
AB = PONG (tag -> reader)
SRIX4K (tag does not respond to 05)
06 00 = INITIATE
0E xx = SELECT ID (xx = Chip-ID)
0B = Get UID
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)
0C = Reset to Inventory
0F = Completion
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
06 00 = INITIATE
0E xx = SELECT ID (xx = Chip-ID)
0B = Get UID
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)
0C = Reset to Inventory
0F = Completion
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
ISO15693
MANDATORY COMMANDS (all ISO15693 tags must support those)
01 = Inventory (usage: 260100+2bytes ISO15693-CRC - answer: 12bytes)
02 = Stay Quiet
OPTIONAL COMMANDS (not all tags support them)
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)
22 = Lock Block
23 = Read Multiple Blocks (usage: 0223+1byte 1st block to read+1byte last block to read+2bytes ISO15693-CRC)
25 = Select
26 = Reset to Ready
27 = Write AFI
28 = Lock AFI
29 = Write DSFID
2A = Lock DSFID
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)
MANDATORY COMMANDS (all ISO15693 tags must support those)
01 = Inventory (usage: 260100+2bytes ISO15693-CRC - answer: 12bytes)
02 = Stay Quiet
OPTIONAL COMMANDS (not all tags support them)
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)
22 = Lock Block
23 = Read Multiple Blocks (usage: 0223+1byte 1st block to read+1byte last block to read+2bytes ISO15693-CRC)
25 = Select
26 = Reset to Ready
27 = Write AFI
28 = Lock AFI
29 = Write DSFID
2A = Lock DSFID
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)
EM Microelectronic CUSTOM COMMANDS
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)
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)
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)
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)
NXP/Philips CUSTOM COMMANDS
A0 = Inventory Read
A1 = Fast Inventory Read
A2 = Set EAS
A3 = Reset EAS
A4 = Lock EAS
A5 = EAS Alarm
A6 = Password Protect EAS
A7 = Write EAS ID
A8 = Read EPC
B0 = Inventory Page Read
B1 = Fast Inventory Page Read
B2 = Get Random Number
B3 = Set Password
B4 = Write Password
B5 = Lock Password
B6 = Bit Password Protection
B7 = Lock Page Protection Condition
B8 = Get Multiple Block Protection Status
B9 = Destroy SLI
BA = Enable Privacy
BB = 64bit Password Protection
40 = Long Range CMD (Standard ISO/TR7003:1990)
A0 = Inventory Read
A1 = Fast Inventory Read
A2 = Set EAS
A3 = Reset EAS
A4 = Lock EAS
A5 = EAS Alarm
A6 = Password Protect EAS
A7 = Write EAS ID
A8 = Read EPC
B0 = Inventory Page Read
B1 = Fast Inventory Page Read
B2 = Get Random Number
B3 = Set Password
B4 = Write Password
B5 = Lock Password
B6 = Bit Password Protection
B7 = Lock Page Protection Condition
B8 = Get Multiple Block Protection Status
B9 = Destroy SLI
BA = Enable Privacy
BB = 64bit Password Protection
40 = Long Range CMD (Standard ISO/TR7003:1990)
ISO 7816-4 Basic interindustry commands. For command APDU's.
B0 = READ BINARY
D0 = WRITE BINARY
D6 = UPDATE BINARY
0E = ERASE BINARY
B2 = READ RECORDS
D2 = WRITE RECORDS
E2 = APPEND RECORD
DC = UPDATE RECORD
CA = GET DATA
DA = PUT DATA
A4 = SELECT FILE
20 = VERIFY
88 = INTERNAL AUTHENTICATION
82 = EXTERNAL AUTHENTICATION
B4 = GET CHALLENGE
70 = MANAGE CHANNEL
B0 = READ BINARY
D0 = WRITE BINARY
D6 = UPDATE BINARY
0E = ERASE BINARY
B2 = READ RECORDS
D2 = WRITE RECORDS
E2 = APPEND RECORD
DC = UPDATE RECORD
CA = GET DATA
DA = PUT DATA
A4 = SELECT FILE
20 = VERIFY
88 = INTERNAL AUTHENTICATION
82 = EXTERNAL AUTHENTICATION
B4 = GET CHALLENGE
70 = MANAGE CHANNEL
For response APDU's
90 00 = OK
6x xx = ERROR
For response APDU's
90 00 = OK
6x xx = ERROR
*/
// these cmds are adjusted to ISO15693 and Manchester encoding requests.
// 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_PAGESEL 0x84
#define ICLASS_CMD_UPDATE 0x87
#define ICLASS_CMD_UPDATE 0x87
#define ICLASS_CMD_READCHECK_KC 0x18
#define ICLASS_CMD_READCHECK_KD 0x88
#define ICLASS_CMD_ACT 0x8E
#define ISO14443A_CMD_REQA 0x26
#define ISO14443A_CMD_READBLOCK 0x30
#define ISO14443A_CMD_WUPA 0x52
#define ISO14443A_CMD_OPTS 0x35
#define ISO14443A_CMD_REQA 0x26
#define ISO14443A_CMD_READBLOCK 0x30
#define ISO14443A_CMD_WUPA 0x52
#define ISO14443A_CMD_OPTS 0x35
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
#define ISO14443A_CMD_WRITEBLOCK 0xA0
#define ISO14443A_CMD_HALT 0x50
#define ISO14443A_CMD_RATS 0xE0
#define ISO14443A_CMD_WRITEBLOCK 0xA0
#define ISO14443A_CMD_HALT 0x50
#define ISO14443A_CMD_RATS 0xE0
#define MIFARE_AUTH_KEYA 0x60
#define MIFARE_AUTH_KEYB 0x61
#define MIFARE_MAGICWUPC1 0x40
#define MIFARE_MAGICWUPC2 0x43
#define MIFARE_MAGICWIPEC 0x41
#define MIFARE_CMD_INC 0xC0
#define MIFARE_CMD_DEC 0xC1
#define MIFARE_CMD_RESTORE 0xC2
#define MIFARE_CMD_TRANSFER 0xB0
#define MIFARE_AUTH_KEYA 0x60
#define MIFARE_AUTH_KEYB 0x61
#define MIFARE_MAGICWUPC1 0x40
#define MIFARE_MAGICWUPC2 0x43
#define MIFARE_MAGICWIPEC 0x41
#define MIFARE_CMD_INC 0xC0
#define MIFARE_CMD_DEC 0xC1
#define MIFARE_CMD_RESTORE 0xC2
#define MIFARE_CMD_TRANSFER 0xB0
#define MIFARE_EV1_PERSONAL_UID 0x40
#define MIFARE_EV1_SETMODE 0x43
#define MIFARE_EV1_PERSONAL_UID 0x40
#define MIFARE_EV1_SETMODE 0x43
#define MIFARE_ULC_WRITE 0xA2
//#define MIFARE_ULC__COMP_WRITE 0xA0
#define MIFARE_ULC_AUTH_1 0x1A
#define MIFARE_ULC_AUTH_2 0xAF
#define MIFARE_ULC_WRITE 0xA2
//#define MIFARE_ULC__COMP_WRITE 0xA0
#define MIFARE_ULC_AUTH_1 0x1A
#define MIFARE_ULC_AUTH_2 0xAF
#define MIFARE_ULEV1_AUTH 0x1B
#define MIFARE_ULEV1_VERSION 0x60
#define MIFARE_ULEV1_FASTREAD 0x3A
#define MIFARE_ULEV1_READ_CNT 0x39
#define MIFARE_ULEV1_INCR_CNT 0xA5
#define MIFARE_ULEV1_READSIG 0x3C
#define MIFARE_ULEV1_CHECKTEAR 0x3E
#define MIFARE_ULEV1_VCSL 0x4B
#define MIFARE_ULEV1_AUTH 0x1B
#define MIFARE_ULEV1_VERSION 0x60
#define MIFARE_ULEV1_FASTREAD 0x3A
#define MIFARE_ULEV1_READ_CNT 0x39
#define MIFARE_ULEV1_INCR_CNT 0xA5
#define MIFARE_ULEV1_READSIG 0x3C
#define MIFARE_ULEV1_CHECKTEAR 0x3E
#define MIFARE_ULEV1_VCSL 0x4B
// 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_LOCKSIF 0xAC
#define MIFARE_ULNANO_WRITESIG 0xA9
#define MIFARE_ULNANO_LOCKSIF 0xAC
// mifare 4bit card answers
#define CARD_ACK 0x0A // 1010 - ACK
#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_IV 0x00 // 0000 - NACK, invalid argument (invalid page address)
#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_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"
// 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 4 - turn off FPGA
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
#define MAGIC_UID 0x01
#define MAGIC_WUPC 0x02
#define MAGIC_HALT 0x04
#define MAGIC_INIT 0x08
#define MAGIC_OFF 0x10
#define MAGIC_DATAIN 0x20
#define MAGIC_WIPE 0x40
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
#define MAGIC_UID 0x01
#define MAGIC_WUPC 0x02
#define MAGIC_HALT 0x04
#define MAGIC_INIT 0x08
#define MAGIC_OFF 0x10
#define MAGIC_DATAIN 0x20
#define MAGIC_WIPE 0x40
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
/**
06 00 = INITIATE
@ -229,8 +229,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define ISO14443B_RESET 0x0C
#define ISO14443B_COMPLETION 0x0F
#define ISO14443B_AUTHENTICATE 0x0A
#define ISO14443B_PING 0xBA
#define ISO14443B_PONG 0xAB
#define ISO14443B_PING 0xBA
#define ISO14443B_PONG 0xAB
//First byte is 26
#define ISO15693_INVENTORY 0x01
@ -251,31 +251,31 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
// Topaz command set:
#define TOPAZ_REQA 0x26 // Request
#define TOPAZ_WUPA 0x52 // WakeUp
#define TOPAZ_RID 0x78 // Read ID
#define TOPAZ_RALL 0x00 // Read All (all bytes)
#define TOPAZ_READ 0x01 // Read (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_REQA 0x26 // Request
#define TOPAZ_WUPA 0x52 // WakeUp
#define TOPAZ_RID 0x78 // Read ID
#define TOPAZ_RALL 0x00 // Read All (all bytes)
#define TOPAZ_READ 0x01 // Read (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)
// additional commands for Dynamic Memory Model
#define TOPAZ_RSEG 0x10 // Read segment
#define TOPAZ_READ8 0x02 // Read (eight bytes)
#define TOPAZ_WRITE_E8 0x54 // Write-with-erase (eight bytes)
#define TOPAZ_WRITE_NE8 0x1B // Write-no-erase (eight bytes)
#define TOPAZ_RSEG 0x10 // Read segment
#define TOPAZ_READ8 0x02 // Read (eight bytes)
#define TOPAZ_WRITE_E8 0x54 // Write-with-erase (eight bytes)
#define TOPAZ_WRITE_NE8 0x1B // Write-no-erase (eight bytes)
// Definitions of which protocol annotations there are available
#define ISO_14443A 0
#define ICLASS 1
#define ISO_14443B 2
#define TOPAZ 3
#define ISO_7816_4 4
#define MFDES 5
#define LEGIC 6
#define ISO_15693 7
#define FELICA 8
#define PROTO_MIFARE 9
#define ISO_14443A 0
#define ICLASS 1
#define ISO_14443B 2
#define TOPAZ 3
#define ISO_7816_4 4
#define MFDES 5
#define LEGIC 6
#define ISO_15693 7
#define FELICA 8
#define PROTO_MIFARE 9
//-- Picopass fuses
#define FUSE_FPERS 0x80
@ -288,131 +288,131 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define FUSE_RA 0x01
// ISO 7816-4 Basic interindustry commands. For command APDU's.
#define ISO7816_READ_BINARY 0xB0
#define ISO7816_WRITE_BINARY 0xD0
#define ISO7816_UPDATE_BINARY 0xD6
#define ISO7816_ERASE_BINARY 0x0E
#define ISO7816_READ_RECORDS 0xB2
#define ISO7816_WRITE_RECORDS 0xD2
#define ISO7816_APPEND_RECORD 0xE2
#define ISO7816_UPDATE_RECORD 0xDC
#define ISO7816_GET_DATA 0xCA
#define ISO7816_PUT_DATA 0xDA
#define ISO7816_SELECT_FILE 0xA4
#define ISO7816_VERIFY 0x20
#define ISO7816_READ_BINARY 0xB0
#define ISO7816_WRITE_BINARY 0xD0
#define ISO7816_UPDATE_BINARY 0xD6
#define ISO7816_ERASE_BINARY 0x0E
#define ISO7816_READ_RECORDS 0xB2
#define ISO7816_WRITE_RECORDS 0xD2
#define ISO7816_APPEND_RECORD 0xE2
#define ISO7816_UPDATE_RECORD 0xDC
#define ISO7816_GET_DATA 0xCA
#define ISO7816_PUT_DATA 0xDA
#define ISO7816_SELECT_FILE 0xA4
#define ISO7816_VERIFY 0x20
#define ISO7816_INTERNAL_AUTHENTICATION 0x88
#define ISO7816_EXTERNAL_AUTHENTICATION 0x82
#define ISO7816_GET_CHALLENGE 0x84
#define ISO7816_MANAGE_CHANNEL 0x70
#define ISO7816_GET_CHALLENGE 0x84
#define ISO7816_MANAGE_CHANNEL 0x70
#define ISO7816_GET_RESPONSE 0xC0
// ISO7816-4 For response APDU's
#define ISO7816_OK 0x9000
// 6x xx = ERROR
#define ISO7816_GET_RESPONSE 0xC0
// ISO7816-4 For response APDU's
#define ISO7816_OK 0x9000
// 6x xx = ERROR
// MIFARE DESFire command set:
#define MFDES_CREATE_APPLICATION 0xca
#define MFDES_DELETE_APPLICATION 0xda
#define MFDES_GET_APPLICATION_IDS 0x6a
#define MFDES_SELECT_APPLICATION 0x5a
#define MFDES_FORMAT_PICC 0xfc
#define MFDES_GET_VERSION 0x60
#define MFDES_READ_DATA 0xbd
#define MFDES_WRITE_DATA 0x3d
#define MFDES_GET_VALUE 0x6c
#define MFDES_CREDIT 0x0c
#define MFDES_DEBIT 0xdc
#define MFDES_LIMITED_CREDIT 0x1c
#define MFDES_WRITE_RECORD 0x3b
#define MFDES_READ_RECORDS 0xbb
#define MFDES_CLEAR_RECORD_FILE 0xeb
#define MFDES_COMMIT_TRANSACTION 0xc7
#define MFDES_ABORT_TRANSACTION 0xa7
#define MFDES_GET_FREE_MEMORY 0x6e
#define MFDES_GET_FILE_IDS 0x6f
#define MFDES_GET_ISOFILE_IDS 0x61
#define MFDES_GET_FILE_SETTINGS 0xf5
#define MFDES_CHANGE_FILE_SETTINGS 0x5f
#define MFDES_CREATE_STD_DATA_FILE 0xcd
#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb
#define MFDES_CREATE_VALUE_FILE 0xcc
#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1
#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0
#define MFDES_DELETE_FILE 0xdf
#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE
#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD
#define MFDES_AUTHENTICATE_AES 0xaa
#define MFDES_CHANGE_KEY_SETTINGS 0x54
#define MFDES_GET_KEY_SETTINGS 0x45
#define MFDES_CHANGE_KEY 0xc4
#define MFDES_GET_KEY_VERSION 0x64
#define MFDES_AUTHENTICATION_FRAME 0xAF
#define MFDES_CREATE_APPLICATION 0xca
#define MFDES_DELETE_APPLICATION 0xda
#define MFDES_GET_APPLICATION_IDS 0x6a
#define MFDES_SELECT_APPLICATION 0x5a
#define MFDES_FORMAT_PICC 0xfc
#define MFDES_GET_VERSION 0x60
#define MFDES_READ_DATA 0xbd
#define MFDES_WRITE_DATA 0x3d
#define MFDES_GET_VALUE 0x6c
#define MFDES_CREDIT 0x0c
#define MFDES_DEBIT 0xdc
#define MFDES_LIMITED_CREDIT 0x1c
#define MFDES_WRITE_RECORD 0x3b
#define MFDES_READ_RECORDS 0xbb
#define MFDES_CLEAR_RECORD_FILE 0xeb
#define MFDES_COMMIT_TRANSACTION 0xc7
#define MFDES_ABORT_TRANSACTION 0xa7
#define MFDES_GET_FREE_MEMORY 0x6e
#define MFDES_GET_FILE_IDS 0x6f
#define MFDES_GET_ISOFILE_IDS 0x61
#define MFDES_GET_FILE_SETTINGS 0xf5
#define MFDES_CHANGE_FILE_SETTINGS 0x5f
#define MFDES_CREATE_STD_DATA_FILE 0xcd
#define MFDES_CREATE_BACKUP_DATA_FILE 0xcb
#define MFDES_CREATE_VALUE_FILE 0xcc
#define MFDES_CREATE_LINEAR_RECORD_FILE 0xc1
#define MFDES_CREATE_CYCLIC_RECORD_FILE 0xc0
#define MFDES_DELETE_FILE 0xdf
#define MFDES_AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE
#define MFDES_AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD
#define MFDES_AUTHENTICATE_AES 0xaa
#define MFDES_CHANGE_KEY_SETTINGS 0x54
#define MFDES_GET_KEY_SETTINGS 0x45
#define MFDES_CHANGE_KEY 0xc4
#define MFDES_GET_KEY_VERSION 0x64
#define MFDES_AUTHENTICATION_FRAME 0xAF
// LEGIC Commands
#define LEGIC_MIM_22 0x0D
#define LEGIC_MIM_256 0x1D
#define LEGIC_MIM_1024 0x3D
#define LEGIC_ACK_22 0x19
#define LEGIC_ACK_256 0x39
#define LEGIC_READ 0x01
#define LEGIC_WRITE 0x00
#define LEGIC_MIM_22 0x0D
#define LEGIC_MIM_256 0x1D
#define LEGIC_MIM_1024 0x3D
#define LEGIC_ACK_22 0x19
#define LEGIC_ACK_256 0x39
#define LEGIC_READ 0x01
#define LEGIC_WRITE 0x00
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);
/* T55x7 configuration register definitions */
#define T55x7_POR_DELAY 0x00000001
#define T55x7_ST_TERMINATOR 0x00000008
#define T55x7_PWD 0x00000010
#define T55x7_MAXBLOCK_SHIFT 5
#define T55x7_AOR 0x00000200
#define T55x7_PSKCF_RF_2 0
#define T55x7_PSKCF_RF_4 0x00000400
#define T55x7_PSKCF_RF_8 0x00000800
#define T55x7_MODULATION_DIRECT 0
#define T55x7_MODULATION_PSK1 0x00001000
#define T55x7_MODULATION_PSK2 0x00002000
#define T55x7_MODULATION_PSK3 0x00003000
#define T55x7_MODULATION_FSK1 0x00004000
#define T55x7_MODULATION_FSK2 0x00005000
#define T55x7_MODULATION_FSK1a 0x00006000
#define T55x7_MODULATION_FSK2a 0x00007000
#define T55x7_MODULATION_MANCHESTER 0x00008000
#define T55x7_MODULATION_BIPHASE 0x00010000
#define T55x7_MODULATION_DIPHASE 0x00018000
#define T55x7_X_MODE 0x00020000
#define T55x7_BITRATE_RF_8 0
#define T55x7_BITRATE_RF_16 0x00040000
#define T55x7_BITRATE_RF_32 0x00080000
#define T55x7_BITRATE_RF_40 0x000C0000
#define T55x7_BITRATE_RF_50 0x00100000
#define T55x7_BITRATE_RF_64 0x00140000
#define T55x7_BITRATE_RF_100 0x00180000
#define T55x7_BITRATE_RF_128 0x001C0000
#define T55x7_TESTMODE_DISABLED 0x60000000
#define T55x7_POR_DELAY 0x00000001
#define T55x7_ST_TERMINATOR 0x00000008
#define T55x7_PWD 0x00000010
#define T55x7_MAXBLOCK_SHIFT 5
#define T55x7_AOR 0x00000200
#define T55x7_PSKCF_RF_2 0
#define T55x7_PSKCF_RF_4 0x00000400
#define T55x7_PSKCF_RF_8 0x00000800
#define T55x7_MODULATION_DIRECT 0
#define T55x7_MODULATION_PSK1 0x00001000
#define T55x7_MODULATION_PSK2 0x00002000
#define T55x7_MODULATION_PSK3 0x00003000
#define T55x7_MODULATION_FSK1 0x00004000
#define T55x7_MODULATION_FSK2 0x00005000
#define T55x7_MODULATION_FSK1a 0x00006000
#define T55x7_MODULATION_FSK2a 0x00007000
#define T55x7_MODULATION_MANCHESTER 0x00008000
#define T55x7_MODULATION_BIPHASE 0x00010000
#define T55x7_MODULATION_DIPHASE 0x00018000
#define T55x7_X_MODE 0x00020000
#define T55x7_BITRATE_RF_8 0
#define T55x7_BITRATE_RF_16 0x00040000
#define T55x7_BITRATE_RF_32 0x00080000
#define T55x7_BITRATE_RF_40 0x000C0000
#define T55x7_BITRATE_RF_50 0x00100000
#define T55x7_BITRATE_RF_64 0x00140000
#define T55x7_BITRATE_RF_100 0x00180000
#define T55x7_BITRATE_RF_128 0x001C0000
#define T55x7_TESTMODE_DISABLED 0x60000000
/* T5555 (Q5) configuration register definitions */
#define T5555_ST_TERMINATOR 0x00000001
#define T5555_MAXBLOCK_SHIFT 0x00000001
#define T5555_MODULATION_MANCHESTER 0
#define T5555_MODULATION_PSK1 0x00000010
#define T5555_MODULATION_PSK2 0x00000020
#define T5555_MODULATION_PSK3 0x00000030
#define T5555_MODULATION_FSK1 0x00000040
#define T5555_MODULATION_FSK2 0x00000050
#define T5555_MODULATION_BIPHASE 0x00000060
#define T5555_MODULATION_DIRECT 0x00000070
#define T5555_INVERT_OUTPUT 0x00000080
#define T5555_PSK_RF_2 0
#define T5555_PSK_RF_4 0x00000100
#define T5555_PSK_RF_8 0x00000200
#define T5555_USE_PWD 0x00000400
#define T5555_USE_AOR 0x00000800
#define T5555_SET_BITRATE(x) (((x-2)/2)<<12)
#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_FAST_WRITE 0x00004000
#define T5555_PAGE_SELECT 0x00008000
#define T5555_ST_TERMINATOR 0x00000001
#define T5555_MAXBLOCK_SHIFT 0x00000001
#define T5555_MODULATION_MANCHESTER 0
#define T5555_MODULATION_PSK1 0x00000010
#define T5555_MODULATION_PSK2 0x00000020
#define T5555_MODULATION_PSK3 0x00000030
#define T5555_MODULATION_FSK1 0x00000040
#define T5555_MODULATION_FSK2 0x00000050
#define T5555_MODULATION_BIPHASE 0x00000060
#define T5555_MODULATION_DIRECT 0x00000070
#define T5555_INVERT_OUTPUT 0x00000080
#define T5555_PSK_RF_2 0
#define T5555_PSK_RF_4 0x00000100
#define T5555_PSK_RF_8 0x00000200
#define T5555_USE_PWD 0x00000400
#define T5555_USE_AOR 0x00000800
#define T5555_SET_BITRATE(x) (((x-2)/2)<<12)
#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_FAST_WRITE 0x00004000
#define T5555_PAGE_SELECT 0x00008000
#define T55XX_WRITE_TIMEOUT 1500
@ -420,152 +420,152 @@ uint32_t GetT55xxClockBit(uint32_t clock);
// em4x05 & em4x69 chip configuration register definitions
#define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2)
#define EM4x05_SET_BITRATE(x) ((x-2)/2)
#define EM4x05_MODULATION_NRZ 0x00000000
#define EM4x05_MODULATION_MANCHESTER 0x00000040
#define EM4x05_MODULATION_BIPHASE 0x00000080
#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_PSK2 0x00000140 //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_FSK2 0x00000240 //not supported by all 4x05/4x69 chips
#define EM4x05_PSK_RF_2 0
#define EM4x05_PSK_RF_4 0x00000400
#define EM4x05_PSK_RF_8 0x00000800
#define EM4x05_MAXBLOCK_SHIFT 14
#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_GET_NUM_BLOCKS(x) (((x>>14) & 0xF)-5+1)
#define EM4x05_READ_LOGIN_REQ 1<<18
#define EM4x05_READ_HK_LOGIN_REQ 1<<19
#define EM4x05_WRITE_LOGIN_REQ 1<<20
#define EM4x05_WRITE_HK_LOGIN_REQ 1<<21
#define EM4x05_READ_AFTER_WRITE 1<<22
#define EM4x05_DISABLE_ALLOWED 1<<23
#define EM4x05_READER_TALK_FIRST 1<<24
#define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2)
#define EM4x05_SET_BITRATE(x) ((x-2)/2)
#define EM4x05_MODULATION_NRZ 0x00000000
#define EM4x05_MODULATION_MANCHESTER 0x00000040
#define EM4x05_MODULATION_BIPHASE 0x00000080
#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_PSK2 0x00000140 //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_FSK2 0x00000240 //not supported by all 4x05/4x69 chips
#define EM4x05_PSK_RF_2 0
#define EM4x05_PSK_RF_4 0x00000400
#define EM4x05_PSK_RF_8 0x00000800
#define EM4x05_MAXBLOCK_SHIFT 14
#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_GET_NUM_BLOCKS(x) (((x>>14) & 0xF)-5+1)
#define EM4x05_READ_LOGIN_REQ 1<<18
#define EM4x05_READ_HK_LOGIN_REQ 1<<19
#define EM4x05_WRITE_LOGIN_REQ 1<<20
#define EM4x05_WRITE_HK_LOGIN_REQ 1<<21
#define EM4x05_READ_AFTER_WRITE 1<<22
#define EM4x05_DISABLE_ALLOWED 1<<23
#define EM4x05_READER_TALK_FIRST 1<<24
// FeliCa protocol
#define FELICA_POLL_REQ 0x00
#define FELICA_POLL_ACK 0x01
#define FELICA_POLL_REQ 0x00
#define FELICA_POLL_ACK 0x01
#define FELICA_REQSRV_REQ 0x02
#define FELICA_REQSRV_ACK 0x03
#define FELICA_REQSRV_REQ 0x02
#define FELICA_REQSRV_ACK 0x03
#define FELICA_REQRESP_REQ 0x04
#define FELICA_REQRESP_ACK 0x05
#define FELICA_REQRESP_REQ 0x04
#define FELICA_REQRESP_ACK 0x05
#define FELICA_RDBLK_REQ 0x06
#define FELICA_RDBLK_ACK 0x07
#define FELICA_RDBLK_REQ 0x06
#define FELICA_RDBLK_ACK 0x07
#define FELICA_WRTBLK_REQ 0x08
#define FELICA_WRTBLK_ACK 0x09
#define FELICA_WRTBLK_REQ 0x08
#define FELICA_WRTBLK_ACK 0x09
#define FELICA_SRCHSYSCODE_REQ 0x0a
#define FELICA_SRCHSYSCODE_ACK 0x0b
#define FELICA_SRCHSYSCODE_REQ 0x0a
#define FELICA_SRCHSYSCODE_ACK 0x0b
#define FELICA_REQSYSCODE_REQ 0x0c
#define FELICA_REQSYSCODE_ACK 0x0d
#define FELICA_REQSYSCODE_REQ 0x0c
#define FELICA_REQSYSCODE_ACK 0x0d
#define FELICA_AUTH1_REQ 0x10
#define FELICA_AUTH1_ACK 0x11
#define FELICA_AUTH1_REQ 0x10
#define FELICA_AUTH1_ACK 0x11
#define FELICA_AUTH2_REQ 0x12
#define FELICA_AUTH2_ACK 0x13
#define FELICA_AUTH2_REQ 0x12
#define FELICA_AUTH2_ACK 0x13
#define FELICA_RDSEC_REQ 0x14
#define FELICA_RDSEC_ACK 0x15
#define FELICA_RDSEC_REQ 0x14
#define FELICA_RDSEC_ACK 0x15
#define FELICA_WRTSEC_REQ 0x16
#define FELICA_WRTSEC_ACK 0x17
#define FELICA_WRTSEC_REQ 0x16
#define FELICA_WRTSEC_ACK 0x17
#define FELICA_REQSRV2_REQ 0x32
#define FELICA_REQSRV2_ACK 0x33
#define FELICA_REQSRV2_REQ 0x32
#define FELICA_REQSRV2_ACK 0x33
#define FELICA_GETSTATUS_REQ 0x38
#define FELICA_GETSTATUS_ACK 0x39
#define FELICA_GETSTATUS_REQ 0x38
#define FELICA_GETSTATUS_ACK 0x39
#define FELICA_OSVER_REQ 0x3c
#define FELICA_OSVER_ACK 0x3d
#define FELICA_OSVER_REQ 0x3c
#define FELICA_OSVER_ACK 0x3d
#define FELICA_RESET_MODE_REQ 0x3e
#define FELICA_RESET_MODE_ACK 0x3f
#define FELICA_RESET_MODE_REQ 0x3e
#define FELICA_RESET_MODE_ACK 0x3f
#define FELICA_AUTH1V2_REQ 0x40
#define FELICA_AUTH1V2_ACK 0x41
#define FELICA_AUTH1V2_REQ 0x40
#define FELICA_AUTH1V2_ACK 0x41
#define FELICA_AUTH2V2_REQ 0x42
#define FELICA_AUTH2V2_ACK 0x43
#define FELICA_AUTH2V2_REQ 0x42
#define FELICA_AUTH2V2_ACK 0x43
#define FELICA_RDSECV2_REQ 0x44
#define FELICA_RDSECV2_ACK 0x45
#define FELICA_WRTSECV2_REQ 0x46
#define FELICA_WRTSECV2_ACK 0x47
#define FELICA_RDSECV2_REQ 0x44
#define FELICA_RDSECV2_ACK 0x45
#define FELICA_WRTSECV2_REQ 0x46
#define FELICA_WRTSECV2_ACK 0x47
#define FELICA_UPDATE_RNDID_REQ 0x4C
#define FELICA_UPDATE_RNDID_ACK 0x4D
#define FELICA_UPDATE_RNDID_REQ 0x4C
#define FELICA_UPDATE_RNDID_ACK 0x4D
// FeliCa SYSTEM list
#define SYSTEMCODE_ANY 0xffff // ANY
#define SYSTEMCODE_FELICA_LITE 0x88b4 // FeliCa Lite
#define SYSTEMCODE_COMMON 0xfe00 // Common
#define SYSTEMCODE_EDY 0xfe00 // Edy
#define SYSTEMCODE_CYBERNE 0x0003 // Cyberne
#define SYSTEMCODE_SUICA 0x0003 // Suica
#define SYSTEMCODE_PASMO 0x0003 // Pasmo
#define SYSTEMCODE_ANY 0xffff // ANY
#define SYSTEMCODE_FELICA_LITE 0x88b4 // FeliCa Lite
#define SYSTEMCODE_COMMON 0xfe00 // Common
#define SYSTEMCODE_EDY 0xfe00 // Edy
#define SYSTEMCODE_CYBERNE 0x0003 // Cyberne
#define SYSTEMCODE_SUICA 0x0003 // Suica
#define SYSTEMCODE_PASMO 0x0003 // Pasmo
//FeliCa Service list Suica/pasmo (little endian)
#define SERVICE_SUICA_INOUT 0x108f // SUICA/PASMO
#define SERVICE_SUICA_HISTORY 0x090f // SUICA/PASMO
#define SERVICE_FELICA_LITE_READONLY 0x0b00 // FeliCa Lite RO
#define SERVICE_FELICA_LITE_READWRITE 0x0900 // FeliCa Lite RW
#define SERVICE_SUICA_INOUT 0x108f // SUICA/PASMO
#define SERVICE_SUICA_HISTORY 0x090f // SUICA/PASMO
#define SERVICE_FELICA_LITE_READONLY 0x0b00 // FeliCa Lite RO
#define SERVICE_FELICA_LITE_READWRITE 0x0900 // FeliCa Lite RW
// Calypso protocol
#define CALYPSO_GET_RESPONSE 0xC0
#define CALYPSO_SELECT 0xA4
#define CALYPSO_INVALIDATE 0x04
#define CALYPSO_REHABILITATE 0x44
#define CALYPSO_APPEND_RECORD 0xE2
#define CALYPSO_DECREASE 0x30
#define CALYPSO_INCREASE 0x32
#define CALYPSO_READ_BINARY 0xB0
#define CALYPSO_READ_RECORD 0xB2
#define CALYPSO_UPDATE_BINARY 0xD6
#define CALYPSO_UPDATE_RECORD 0xDC
#define CALYPSO_WRITE_RECORD 0xD2
#define CALYPSO_OPEN_SESSION 0x8A
#define CALYPSO_CLOSE_SESSION 0x8E
#define CALYPSO_GET_CHALLENGE 0x84
#define CALYPSO_CHANGE_PIN 0xD8
#define CALYPSO_VERIFY_PIN 0x20
#define CALYPSO_SV_GET 0x7C
#define CALYPSO_SV_DEBIT 0xBA
#define CALYPSO_SV_RELOAD 0xB8
#define CALYPSO_SV_UN_DEBIT 0xBC
#define CALYPSO_SAM_SV_DEBIT 0x54
#define CALYPSO_SAM_SV_RELOAD 0x56
#define CALYPSO_GET_RESPONSE 0xC0
#define CALYPSO_SELECT 0xA4
#define CALYPSO_INVALIDATE 0x04
#define CALYPSO_REHABILITATE 0x44
#define CALYPSO_APPEND_RECORD 0xE2
#define CALYPSO_DECREASE 0x30
#define CALYPSO_INCREASE 0x32
#define CALYPSO_READ_BINARY 0xB0
#define CALYPSO_READ_RECORD 0xB2
#define CALYPSO_UPDATE_BINARY 0xD6
#define CALYPSO_UPDATE_RECORD 0xDC
#define CALYPSO_WRITE_RECORD 0xD2
#define CALYPSO_OPEN_SESSION 0x8A
#define CALYPSO_CLOSE_SESSION 0x8E
#define CALYPSO_GET_CHALLENGE 0x84
#define CALYPSO_CHANGE_PIN 0xD8
#define CALYPSO_VERIFY_PIN 0x20
#define CALYPSO_SV_GET 0x7C
#define CALYPSO_SV_DEBIT 0xBA
#define CALYPSO_SV_RELOAD 0xB8
#define CALYPSO_SV_UN_DEBIT 0xBC
#define CALYPSO_SAM_SV_DEBIT 0x54
#define CALYPSO_SAM_SV_RELOAD 0x56
// iclass / picopass chip config structures and shared routines
typedef struct {
uint8_t app_limit; //[8]
uint8_t otp[2]; //[9-10]
uint8_t block_writelock;//[11]
uint8_t chip_config; //[12]
uint8_t mem_config; //[13]
uint8_t eas; //[14]
uint8_t fuses; //[15]
uint8_t app_limit; //[8]
uint8_t otp[2]; //[9-10]
uint8_t block_writelock;//[11]
uint8_t chip_config; //[12]
uint8_t mem_config; //[13]
uint8_t eas; //[14]
uint8_t fuses; //[15]
} picopass_conf_block;
typedef struct {
uint8_t csn[8];
picopass_conf_block conf;
uint8_t epurse[8];
uint8_t key_d[8];
uint8_t key_c[8];
uint8_t app_issuer_area[8];
uint8_t csn[8];
picopass_conf_block conf;
uint8_t epurse[8];
uint8_t key_d[8];
uint8_t key_c[8];
uint8_t app_issuer_area[8];
} picopass_hdr;

View file

@ -14,17 +14,17 @@ static uint32_t g_nextrandom;
*/
inline void fast_prand(){
fast_prandEx(GetTickCount());
fast_prandEx(GetTickCount());
}
inline void fast_prandEx(uint32_t seed) {
g_nextrandom = seed;
g_nextrandom = seed;
}
uint32_t prand() {
// g_nextrandom *= 6364136223846793005;
// g_nextrandom += 1;
// g_nextrandom *= 6364136223846793005;
// g_nextrandom += 1;
//return (uint32_t)(g_nextrandom >> 32) % 0xffffffff;
g_nextrandom = (214013 * g_nextrandom + 2531011);
return (g_nextrandom>>16) & 0xFFFF;
g_nextrandom = (214013 * g_nextrandom + 2531011);
return (g_nextrandom>>16) & 0xFFFF;
}

View file

@ -13,52 +13,52 @@
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 sum = 0;
uint8_t n = ROUNDS;
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
uint32_t sum = 0;
uint8_t n = ROUNDS;
//key
a = bytes_to_num(key, 4);
b = bytes_to_num(key+4, 4);
c = bytes_to_num(key+8, 4);
d = bytes_to_num(key+12, 4);
//key
a = bytes_to_num(key, 4);
b = bytes_to_num(key+4, 4);
c = bytes_to_num(key+8, 4);
d = bytes_to_num(key+12, 4);
//input
y = bytes_to_num(v, 4);
z = bytes_to_num(v+4, 4);
//input
y = bytes_to_num(v, 4);
z = bytes_to_num(v+4, 4);
while ( n-- > 0 ) {
sum += DELTA;
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
}
while ( n-- > 0 ) {
sum += DELTA;
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
}
num_to_bytes(y, 4, v);
num_to_bytes(z, 4, v+4);
num_to_bytes(y, 4, v);
num_to_bytes(z, 4, v+4);
}
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 sum = SUM;
uint8_t n = ROUNDS;
uint32_t a=0,b=0,c=0,d=0,y=0,z=0;
uint32_t sum = SUM;
uint8_t n = ROUNDS;
//key
a = bytes_to_num(key, 4);
b = bytes_to_num(key+4, 4);
c = bytes_to_num(key+8, 4);
d = bytes_to_num(key+12, 4);
//key
a = bytes_to_num(key, 4);
b = bytes_to_num(key+4, 4);
c = bytes_to_num(key+8, 4);
d = bytes_to_num(key+12, 4);
//input
y = bytes_to_num(v, 4);
z = bytes_to_num(v+4, 4);
//input
y = bytes_to_num(v, 4);
z = bytes_to_num(v+4, 4);
/* sum = delta<<5, in general sum = delta * n */
while ( n-- > 0 ) {
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
sum -= DELTA;
}
num_to_bytes(y, 4, v);
num_to_bytes(z, 4, v+4);
/* sum = delta<<5, in general sum = delta * n */
while ( n-- > 0 ) {
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
sum -= DELTA;
}
num_to_bytes(y, 4, v);
num_to_bytes(z, 4, v+4);
}

View file

@ -11,19 +11,19 @@
#include "usart.h"
#include "string.h"
#define AT91_BAUD_RATE 115200
#define AT91_BAUD_RATE 115200
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
/*
void usart_close(void) {
// Reset the USART mode
pUS1->US_MR = 0;
pUS1->US_MR = 0;
// Reset the baud rate divisor register
pUS1->US_BRGR = 0;
pUS1->US_BRGR = 0;
// Reset the Timeguard Register
pUS1->US_TTGR = 0;
@ -32,7 +32,7 @@ void usart_close(void) {
pUS1->US_IDR = 0xFFFFFFFF;
// 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
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).
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)) {
pUS1->US_RPR = (uint32_t)data;
pUS1->US_RCR = len;
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
return 2;
}
// 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_RNCR = len;
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS;
return 1;
} else {
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
if (!(pUS1->US_TCR)) {
memcpy(us_outbuf, data, len);
pUS1->US_TPR = (uint32_t)us_outbuf;
memcpy(us_outbuf, data, len);
pUS1->US_TPR = (uint32_t)us_outbuf;
pUS1->US_TCR = sizeof(us_outbuf);
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
return 2;
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
return 2;
}
// Check if the second PDC bank is free
else if (!(pUS1->US_TNCR)) {
memcpy(us_outbuf, data, len);
memcpy(us_outbuf, data, len);
pUS1->US_TNPR = (uint32_t)us_outbuf;
pUS1->US_TNCR = sizeof(us_outbuf);
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
return 1;
pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS;
return 1;
} else {
return 0;
}
@ -94,21 +94,21 @@ inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
void usart_init(void) {
// disable & reset receiver / transmitter for configuration
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS);
// disable & reset receiver / transmitter for configuration
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS);
//enable the USART1 Peripheral clock
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
//enable the USART1 Peripheral clock
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
// disable PIO control of receive / transmit pins
pPIO->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// disable PIO control of receive / transmit pins
pPIO->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// enable peripheral mode A on receive / transmit pins
pPIO->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
pPIO->PIO_BSR = 0;
// enable peripheral mode A on receive / transmit pins
pPIO->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
pPIO->PIO_BSR = 0;
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
pPIO->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
pPIO->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// set 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_CHMODE_NORMAL; // channel mode: normal
// all interrupts disabled
pUS1->US_IDR = 0xFFFF;
// all interrupts disabled
pUS1->US_IDR = 0xFFFF;
// iceman, setting 115200 doesn't work. Only speed I got to work is 9600.
// something fishy with the AT91SAM7S512 USART.. Or I missed something
// For a nice detailed sample, interrupt driven but still relevant.
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
// iceman, setting 115200 doesn't work. Only speed I got to work is 9600.
// something fishy with the AT91SAM7S512 USART.. Or I missed something
// For a nice detailed sample, interrupt driven but still relevant.
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
// set baudrate to 115200
// 115200 * 16 == 1843200
//
//pUS1->US_BRGR = (48UL*1000*1000) / (9600*16);
pUS1->US_BRGR = 48054841 / (9600 << 4);
// set baudrate to 115200
// 115200 * 16 == 1843200
//
//pUS1->US_BRGR = (48UL*1000*1000) / (9600*16);
pUS1->US_BRGR = 48054841 / (9600 << 4);
// Write the Timeguard Register
pUS1->US_TTGR = 0;
pUS1->US_RTOR = 0;
pUS1->US_FIDI = 0;
pUS1->US_IF = 0;
// Write the Timeguard Register
pUS1->US_TTGR = 0;
pUS1->US_RTOR = 0;
pUS1->US_FIDI = 0;
pUS1->US_IF = 0;
// re-enable receiver / transmitter
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
// re-enable receiver / transmitter
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
}

File diff suppressed because it is too large Load diff

View file

@ -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),
// 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) {
uint32_t parityWd = 0;
size_t j = 0, bitcount = 0;
for (int word = 0; word < (bLen); word += pLen){
for (int bit = 0; bit < pLen; ++bit){
parityWd = (parityWd << 1) | bitstream[startIdx+word+bit];
bitstream[j++] = (bitstream[startIdx + word + bit]);
}
j--; // overwrite parity with next data
// if parity fails then return 0
switch (pType) {
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
default: //test parity
if (parityTest(parityWd, pLen, pType) == 0) return 0; break;
}
bitcount += ( pLen - 1 );
parityWd = 0;
}
// if we got here then all the parities passed
//return ID start index and size
return bitcount;
uint32_t parityWd = 0;
size_t j = 0, bitcount = 0;
for (int word = 0; word < (bLen); word += pLen){
for (int bit = 0; bit < pLen; ++bit){
parityWd = (parityWd << 1) | bitstream[startIdx+word+bit];
bitstream[j++] = (bitstream[startIdx + word + bit]);
}
j--; // overwrite parity with next data
// if parity fails then return 0
switch (pType) {
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
default: //test parity
if (parityTest(parityWd, pLen, pType) == 0) return 0; break;
}
bitcount += ( pLen - 1 );
parityWd = 0;
}
// if we got here then all the parities passed
//return ID start index and size
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)
{
uint32_t parityWd = 0;
size_t j = 0, bitCnt = 0;
for (int word = 0; word < sourceLen; word += pLen-1) {
for (int bit = 0; bit < pLen-1; ++bit){
parityWd = (parityWd << 1) | bits[word+bit];
dest[j++] = (bits[word+bit]);
}
uint32_t parityWd = 0;
size_t j = 0, bitCnt = 0;
for (int word = 0; word < sourceLen; word += pLen-1) {
for (int bit = 0; bit < pLen-1; ++bit){
parityWd = (parityWd << 1) | bits[word+bit];
dest[j++] = (bits[word+bit]);
}
// if parity fails then return 0
switch (pType) {
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
default:
dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1;
break;
}
bitCnt += pLen;
parityWd = 0;
}
// if we got here then all the parities passed
//return ID start index and size
return bitCnt;
// if parity fails then return 0
switch (pType) {
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
default:
dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1;
break;
}
bitCnt += pLen;
parityWd = 0;
}
// if we got here then all the parities passed
//return ID start index and size
return bitCnt;
}
// 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) {
// 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);
// half length, Even and Odd is calculated to the middle.
uint8_t len_h2 = length >> 1;
// half length, Even and Odd is calculated to the middle.
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 += length + 1;
// add ODD parity at the very end
// add ODD parity at the very end
*(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){
uint8_t data[MAX_BITS_TXX55] = {0};
memset(data, 0, sizeof(data));
uint8_t data[MAX_BITS_TXX55] = {0};
memset(data, 0, sizeof(data));
num_to_wiegand_bits(oem, fc, cn, data, formatlen);
num_to_wiegand_bits(oem, fc, cn, data, formatlen);
// loop
// (formatlen / 32 ) + 1
// (formatlen >> 5) + 1
for (int i = 0; i < formatlen ; ++i){
uint32_t value = bytebits_to_byte( data + (i * 32), 32);
num_to_bytes(value, 32, dest + (i*4) );
}
// loop
// (formatlen / 32 ) + 1
// (formatlen >> 5) + 1
for (int i = 0; i < formatlen ; ++i){
uint32_t value = bytebits_to_byte( data + (i * 32), 32);
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){
uint8_t bits[MAX_BITS_TXX55] = {0};
memset(bits, 0, sizeof(bits));
uint8_t *temp = bits;
uint64_t value = 0;
uint8_t bits[MAX_BITS_TXX55] = {0};
memset(bits, 0, sizeof(bits));
uint8_t *temp = bits;
uint64_t value = 0;
switch ( formatlen ){
case 26 : // 26bit HID H10301
fc &= 0xFF; // 8bits
cn &= 0xFFFF; // 16bits
value = fc << 16 | cn;
num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24);
break;
case 261: // 26bit Indala
fc &= 0xFFF; // 12bits
cn &= 0xFFF; // 12bits
value = fc << 12 | cn;
num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24);
break;
case 34 : // 34bits HID
fc &= 0xFFFF; // 16bits
cn &= 0xFFFF; // 16bits
value = fc << 16 | cn;
num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32);
break;
case 35 : // 35bits HID
fc &= 0xFFF; // 12bits
cn &= 0xFFFFFF; // 20bits
value = fc << 20 | cn;
num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32);
break;
case 37 : // H10304
fc &= 0xFFFF; // 16bits
cn &= 0x7FFFF; // 19bits
value = fc << 19 | cn;
num_to_bytebits(value, 35, temp);
wiegand_add_parity(temp, dest, 35);
break;
case 39 : // 39bit KERI System Pyramid
fc &= 0x1FFFF; // 17bits
cn &= 0xFFFFFFFF; // 20bits
value = fc << 20 | cn;
num_to_bytebits(value, 37, temp);
wiegand_add_parity(temp, dest, 37);
break;
case 44 : // 44bit KERI system Pyramid
oem &= 0xFF; // 8bits
fc &= 0xFFF; // 12bits
cn &= 0xFFFFFFFF; // 21bits
value = oem << 20 | fc << 12 | cn;
num_to_bytebits(value, 42, temp);
wiegand_add_parity(temp, dest, 42);
break;
case 50 : // AWID 50 RBH
fc &= 0xFFFF; // 16bits
cn &= 0xFFFFFFFF // 32bits
value = fc << 32 | cn;
num_to_bytebits(value, 48, temp);
wiegand_add_parity(temp, dest, 48); // verify!
break;
default:
break;
}
switch ( formatlen ){
case 26 : // 26bit HID H10301
fc &= 0xFF; // 8bits
cn &= 0xFFFF; // 16bits
value = fc << 16 | cn;
num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24);
break;
case 261: // 26bit Indala
fc &= 0xFFF; // 12bits
cn &= 0xFFF; // 12bits
value = fc << 12 | cn;
num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24);
break;
case 34 : // 34bits HID
fc &= 0xFFFF; // 16bits
cn &= 0xFFFF; // 16bits
value = fc << 16 | cn;
num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32);
break;
case 35 : // 35bits HID
fc &= 0xFFF; // 12bits
cn &= 0xFFFFFF; // 20bits
value = fc << 20 | cn;
num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32);
break;
case 37 : // H10304
fc &= 0xFFFF; // 16bits
cn &= 0x7FFFF; // 19bits
value = fc << 19 | cn;
num_to_bytebits(value, 35, temp);
wiegand_add_parity(temp, dest, 35);
break;
case 39 : // 39bit KERI System Pyramid
fc &= 0x1FFFF; // 17bits
cn &= 0xFFFFFFFF; // 20bits
value = fc << 20 | cn;
num_to_bytebits(value, 37, temp);
wiegand_add_parity(temp, dest, 37);
break;
case 44 : // 44bit KERI system Pyramid
oem &= 0xFF; // 8bits
fc &= 0xFFF; // 12bits
cn &= 0xFFFFFFFF; // 21bits
value = oem << 20 | fc << 12 | cn;
num_to_bytebits(value, 42, temp);
wiegand_add_parity(temp, dest, 42);
break;
case 50 : // AWID 50 RBH
fc &= 0xFFFF; // 16bits
cn &= 0xFFFFFFFF // 32bits
value = fc << 32 | cn;
num_to_bytebits(value, 48, temp);
wiegand_add_parity(temp, dest, 48); // verify!
break;
default:
break;
}
}