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" #include "bucketsort.h"
extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop, extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
uint32_t* const ostart, uint32_t* const ostop, uint32_t* const ostart, uint32_t* const ostop,
bucket_info_t *bucket_info, bucket_array_t bucket) bucket_info_t *bucket_info, bucket_array_t bucket)
{ {
uint32_t *p1, *p2; uint32_t *p1, *p2;
uint32_t *start[2]; uint32_t *start[2];
uint32_t *stop[2]; uint32_t *stop[2];
start[0] = estart; start[0] = estart;
stop[0] = estop; stop[0] = estop;
start[1] = ostart; start[1] = ostart;
stop[1] = ostop; stop[1] = ostop;
// init buckets to be empty // init buckets to be empty
for (uint32_t i = 0; i < 2; i++) { for (uint32_t i = 0; i < 2; i++) {
for (uint32_t j = 0x00; j <= 0xff; j++) { for (uint32_t j = 0x00; j <= 0xff; j++) {
bucket[i][j].bp = bucket[i][j].head; bucket[i][j].bp = bucket[i][j].head;
} }
} }
// sort the lists into the buckets based on the MSB (contribution bits) // sort the lists into the buckets based on the MSB (contribution bits)
for (uint32_t i = 0; i < 2; i++) { for (uint32_t i = 0; i < 2; i++) {
for (p1 = start[i]; p1 <= stop[i]; p1++) { for (p1 = start[i]; p1 <= stop[i]; p1++) {
uint32_t bucket_index = (*p1 & 0xff000000) >> 24; uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
*(bucket[i][bucket_index].bp++) = *p1; *(bucket[i][bucket_index].bp++) = *p1;
} }
} }
// write back intersecting buckets as sorted list. // write back intersecting buckets as sorted list.
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets. // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
uint32_t nonempty_bucket; uint32_t nonempty_bucket;
for (uint32_t i = 0; i < 2; i++) { for (uint32_t i = 0; i < 2; i++) {
p1 = start[i]; p1 = start[i];
nonempty_bucket = 0; nonempty_bucket = 0;
for (uint32_t j = 0x00; j <= 0xff; j++) { for (uint32_t j = 0x00; j <= 0xff; j++) {
if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
bucket_info->bucket_info[i][nonempty_bucket].head = p1; bucket_info->bucket_info[i][nonempty_bucket].head = p1;
for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++); for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1; bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
nonempty_bucket++; nonempty_bucket++;
} }
} }
bucket_info->numbuckets = nonempty_bucket; bucket_info->numbuckets = nonempty_bucket;
} }
} }

View file

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

View file

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

View file

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

View file

@ -28,7 +28,7 @@ extern "C" {
#endif #endif
struct Crypto1State {uint32_t odd, even;}; struct Crypto1State {uint32_t odd, even;};
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() #if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
void crypto1_create(struct Crypto1State *s, uint64_t key); void crypto1_create(struct Crypto1State *s, uint64_t key);
#else #else
struct Crypto1State *crypto1_create(uint64_t key); struct Crypto1State *crypto1_create(uint64_t key);
@ -53,15 +53,15 @@ uint32_t lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
int nonce_distance(uint32_t from, uint32_t to); int nonce_distance(uint32_t from, uint32_t to);
extern bool validate_prng_nonce(uint32_t nonce); extern bool validate_prng_nonce(uint32_t nonce);
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ #define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
uint32_t __n = 0,__M = 0, N = 0;\ uint32_t __n = 0,__M = 0, N = 0;\
int __i;\ int __i;\
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\ for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
for(__i = FSIZE - 1; __i >= 0; __i--)\ for(__i = FSIZE - 1; __i >= 0; __i--)\
if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\ if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
break;\ break;\
else if(__i)\ else if(__i)\
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\ __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
else else
#define LF_POLY_ODD (0x29CE5C) #define LF_POLY_ODD (0x29CE5C)
#define LF_POLY_EVEN (0x870804) #define LF_POLY_EVEN (0x870804)
@ -69,14 +69,14 @@ extern bool validate_prng_nonce(uint32_t nonce);
#define BEBIT(x, n) BIT(x, (n) ^ 24) #define BEBIT(x, n) BIT(x, (n) ^ 24)
static inline int filter(uint32_t const x) static inline int filter(uint32_t const x)
{ {
uint32_t f; uint32_t f;
f = 0xf22c0 >> (x & 0xf) & 16; f = 0xf22c0 >> (x & 0xf) & 16;
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
f |= 0x1e458 >> (x >> 12 & 0xf) & 2; f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1; f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
return BIT(0xEC57E80A, f); return BIT(0xEC57E80A, f);
} }
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

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

View file

@ -10,118 +10,118 @@
#include "crc.h" #include "crc.h"
void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) { void crc_init_ref(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor, bool refin, bool refout) {
crc_init(crc, order, polynom, initial_value, final_xor); crc_init(crc, order, polynom, initial_value, final_xor);
crc->refin = refin; crc->refin = refin;
crc->refout = refout; crc->refout = refout;
crc_clear(crc); crc_clear(crc);
} }
void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) { void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor) {
crc->order = order; crc->order = order;
crc->topbit = BITMASK( order-1 ); crc->topbit = BITMASK( order-1 );
crc->polynom = polynom; crc->polynom = polynom;
crc->initial_value = initial_value; crc->initial_value = initial_value;
crc->final_xor = final_xor; crc->final_xor = final_xor;
crc->mask = (1L<<order)-1; crc->mask = (1L<<order)-1;
crc->refin = false; crc->refin = false;
crc->refout = false; crc->refout = false;
crc_clear(crc); crc_clear(crc);
} }
void crc_clear(crc_t *crc) { void crc_clear(crc_t *crc) {
crc->state = crc->initial_value & crc->mask; crc->state = crc->initial_value & crc->mask;
if (crc->refin) if (crc->refin)
crc->state = reflect(crc->state, crc->order); crc->state = reflect(crc->state, crc->order);
} }
void crc_update2(crc_t *crc, uint32_t data, int data_width){ void crc_update2(crc_t *crc, uint32_t data, int data_width){
if (crc->refin) if (crc->refin)
data = reflect(data, data_width); data = reflect(data, data_width);
// Bring the next byte into the remainder. // Bring the next byte into the remainder.
crc->state ^= data << (crc->order - data_width); crc->state ^= data << (crc->order - data_width);
for( uint8_t bit = data_width; bit > 0; --bit) { for( uint8_t bit = data_width; bit > 0; --bit) {
if (crc->state & crc->topbit) if (crc->state & crc->topbit)
crc->state = (crc->state << 1) ^ crc->polynom; crc->state = (crc->state << 1) ^ crc->polynom;
else else
crc->state = (crc->state << 1); crc->state = (crc->state << 1);
} }
} }
void crc_update(crc_t *crc, uint32_t data, int data_width) void crc_update(crc_t *crc, uint32_t data, int data_width)
{ {
if (crc->refin) if (crc->refin)
data = reflect(data, data_width); data = reflect(data, data_width);
int i; int i;
for(i=0; i<data_width; i++) { for(i=0; i<data_width; i++) {
int oldstate = crc->state; int oldstate = crc->state;
crc->state = crc->state >> 1; crc->state = crc->state >> 1;
if( (oldstate^data) & 1 ) { if( (oldstate^data) & 1 ) {
crc->state ^= crc->polynom; crc->state ^= crc->polynom;
} }
data >>= 1; data >>= 1;
} }
} }
uint32_t crc_finish(crc_t *crc) { uint32_t crc_finish(crc_t *crc) {
uint32_t val = crc->state; uint32_t val = crc->state;
if (crc->refout) if (crc->refout)
val = reflect(val, crc->order); val = reflect(val, crc->order);
return ( val ^ crc->final_xor ) & crc->mask; return ( val ^ crc->final_xor ) & crc->mask;
} }
/* /*
static void print_crc(crc_t *crc) { static void print_crc(crc_t *crc) {
printf(" Order %d\n Poly %x\n Init %x\n Final %x\n Mask %x\n topbit %x\n RefIn %s\n RefOut %s\n State %x\n", printf(" Order %d\n Poly %x\n Init %x\n Final %x\n Mask %x\n topbit %x\n RefIn %s\n RefOut %s\n State %x\n",
crc->order, crc->order,
crc->polynom, crc->polynom,
crc->initial_value, crc->initial_value,
crc->final_xor, crc->final_xor,
crc->mask, crc->mask,
crc->topbit, crc->topbit,
(crc->refin) ? "TRUE":"FALSE", (crc->refin) ? "TRUE":"FALSE",
(crc->refout) ? "TRUE":"FALSE", (crc->refout) ? "TRUE":"FALSE",
crc->state crc->state
); );
} }
*/ */
// width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xA1 name="CRC-8/MAXIM" // width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xA1 name="CRC-8/MAXIM"
uint32_t CRC8Maxim(uint8_t *buff, size_t size) { uint32_t CRC8Maxim(uint8_t *buff, size_t size) {
crc_t crc; crc_t crc;
crc_init_ref(&crc, 8, 0x31, 0, 0, true, true); crc_init_ref(&crc, 8, 0x31, 0, 0, true, true);
for ( int i=0; i < size; ++i) for ( int i=0; i < size; ++i)
crc_update2(&crc, buff[i], 8); crc_update2(&crc, buff[i], 8);
return crc_finish(&crc); return crc_finish(&crc);
} }
// width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD" // width=8 poly=0x1d, init=0xc7 (0xe3 - WRONG! but it mentioned in MAD datasheet) refin=false refout=false xorout=0x00 name="CRC-8/MIFARE-MAD"
uint32_t CRC8Mad(uint8_t *buff, size_t size) { uint32_t CRC8Mad(uint8_t *buff, size_t size) {
crc_t crc; crc_t crc;
crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false); crc_init_ref(&crc, 8, 0x1d, 0xc7, 0, false, false);
for ( int i = 0; i < size; ++i) for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8); crc_update2(&crc, buff[i], 8);
return crc_finish(&crc); return crc_finish(&crc);
} }
// width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC" // width=4 poly=0xC, reversed poly=0x7 init=0x5 refin=true refout=true xorout=0x0000 check= name="CRC-4/LEGIC"
uint32_t CRC4Legic(uint8_t *cmd, size_t size) { uint32_t CRC4Legic(uint8_t *cmd, size_t size) {
crc_t crc; crc_t crc;
crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true); crc_init_ref(&crc, 4, 0x19 >> 1, 0x5, 0, true, true);
crc_update2(&crc, 1, 1); /* CMD_READ */ crc_update2(&crc, 1, 1); /* CMD_READ */
crc_update2(&crc, cmd[0], 8); crc_update2(&crc, cmd[0], 8);
crc_update2(&crc, cmd[1], 8); crc_update2(&crc, cmd[1], 8);
return reflect(crc_finish(&crc), 4); return reflect(crc_finish(&crc), 4);
} }
// width=8 poly=0x63, reversed poly=0x8D init=0x55 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/LEGIC" // width=8 poly=0x63, reversed poly=0x8D init=0x55 refin=true refout=true xorout=0x0000 check=0xC6 name="CRC-8/LEGIC"
// the CRC needs to be reversed before returned. // the CRC needs to be reversed before returned.
uint32_t CRC8Legic(uint8_t *buff, size_t size) { uint32_t CRC8Legic(uint8_t *buff, size_t size) {
crc_t crc; crc_t crc;
crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true); crc_init_ref(&crc, 8, 0x63, 0x55, 0, true, true);
for ( int i = 0; i < size; ++i) for ( int i = 0; i < size; ++i)
crc_update2(&crc, buff[i], 8); crc_update2(&crc, buff[i], 8);
return reflect8(crc_finish(&crc)); return reflect8(crc_finish(&crc));
} }

View file

@ -9,19 +9,19 @@
#ifndef __CRC_H #ifndef __CRC_H
#define __CRC_H #define __CRC_H
#include "common.h" //stdint, stddef, stdbool #include "common.h" //stdint, stddef, stdbool
#include "util.h" // reflect, bswap_16 #include "util.h" // reflect, bswap_16
typedef struct crc { typedef struct crc {
uint32_t state; uint32_t state;
int order; int order;
uint32_t polynom; uint32_t polynom;
uint32_t initial_value; uint32_t initial_value;
uint32_t final_xor; uint32_t final_xor;
uint32_t mask; uint32_t mask;
int topbit; int topbit;
bool refin; /* Parameter: Reflect input bytes? */ bool refin; /* Parameter: Reflect input bytes? */
bool refout; /* Parameter: Reflect output CRC? */ bool refout; /* Parameter: Reflect output CRC? */
} crc_t; } crc_t;
/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 /* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32
@ -64,14 +64,14 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size);
/* Static initialization of a crc structure */ /* Static initialization of a crc structure */
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ #define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
.state = ((_initial_value) & ((1L<<(_order))-1)), \ .state = ((_initial_value) & ((1L<<(_order))-1)), \
.order = (_order), \ .order = (_order), \
.polynom = (_polynom), \ .polynom = (_polynom), \
.initial_value = (_initial_value), \ .initial_value = (_initial_value), \
.final_xor = (_final_xor), \ .final_xor = (_final_xor), \
.mask = ((1L<<(_order))-1) \ .mask = ((1L<<(_order))-1) \
.refin = false, \ .refin = false, \
.refout = false \ .refout = false \
} }
#endif /* __CRC_H */ #endif /* __CRC_H */

View file

@ -13,125 +13,125 @@ static CrcType_t crc_type = CRC_NONE;
void init_table(CrcType_t ct) { void init_table(CrcType_t ct) {
// same crc algo, and initialised already // same crc algo, and initialised already
if ( ct == crc_type && crc_table_init) if ( ct == crc_type && crc_table_init)
return; return;
// not the same crc algo. reset table. // not the same crc algo. reset table.
if ( ct != crc_type) if ( ct != crc_type)
reset_table(); reset_table();
crc_type = ct; crc_type = ct;
switch (ct) { switch (ct) {
case CRC_14443_A: case CRC_14443_A:
case CRC_14443_B: case CRC_14443_B:
case CRC_15693: case CRC_15693:
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break; case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break; case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break; case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break; case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break; case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
default: default:
crc_table_init = false; crc_table_init = false;
crc_type = CRC_NONE; crc_type = CRC_NONE;
break; break;
} }
} }
void generate_table( uint16_t polynomial, bool refin) { void generate_table( uint16_t polynomial, bool refin) {
uint16_t i, j, crc, c; uint16_t i, j, crc, c;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
crc = 0; crc = 0;
if (refin) if (refin)
c = reflect8(i) << 8; c = reflect8(i) << 8;
else else
c = i << 8; c = i << 8;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
if ( (crc ^ c) & 0x8000 ) if ( (crc ^ c) & 0x8000 )
crc = ( crc << 1 ) ^ polynomial; crc = ( crc << 1 ) ^ polynomial;
else else
crc = crc << 1; crc = crc << 1;
c = c << 1; c = c << 1;
} }
if (refin) if (refin)
crc = reflect16(crc); crc = reflect16(crc);
crc_table[i] = crc; crc_table[i] = crc;
} }
crc_table_init = true; crc_table_init = true;
} }
void reset_table(void) { void reset_table(void) {
memset(crc_table, 0, sizeof(crc_table)); memset(crc_table, 0, sizeof(crc_table));
crc_table_init = false; crc_table_init = false;
crc_type = CRC_NONE; crc_type = CRC_NONE;
} }
// table lookup LUT solution // table lookup LUT solution
uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout) { uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout) {
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip. // fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
// only usable with polynom orders of 8, 16, 24 or 32. // only usable with polynom orders of 8, 16, 24 or 32.
if (n == 0) if (n == 0)
return (~initval); return (~initval);
uint16_t crc = initval; uint16_t crc = initval;
if (refin) if (refin)
crc = reflect16(crc); crc = reflect16(crc);
if (!refin) if (!refin)
while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ]; while (n--) crc = (crc << 8) ^ crc_table[ ((crc >> 8) ^ *d++) & 0xFF ];
else else
while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++]; while (n--) crc = (crc >> 8) ^ crc_table[ (crc & 0xFF) ^ *d++];
if (refout^refin) if (refout^refin)
crc = reflect16(crc); crc = reflect16(crc);
return crc; return crc;
} }
// bit looped solution TODO REMOVED // bit looped solution TODO REMOVED
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) { uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
uint16_t i, v, tmp = 0; uint16_t i, v, tmp = 0;
v = (crc ^ c) & 0xff; v = (crc ^ c) & 0xff;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if ( (tmp ^ v) & 1 ) if ( (tmp ^ v) & 1 )
tmp = ( tmp >> 1 ) ^ polynomial; tmp = ( tmp >> 1 ) ^ polynomial;
else else
tmp >>= 1; tmp >>= 1;
v >>= 1; v >>= 1;
} }
return ((crc >> 8) ^ tmp) & 0xffff; return ((crc >> 8) ^ tmp) & 0xffff;
} }
uint16_t update_crc16( uint16_t crc, uint8_t c ) { uint16_t update_crc16( uint16_t crc, uint8_t c ) {
return update_crc16_ex( crc, c, CRC16_POLY_CCITT); return update_crc16_ex( crc, c, CRC16_POLY_CCITT);
} }
// two ways. msb or lsb loop. // two ways. msb or lsb loop.
uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) { uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) {
if (length == 0) if (length == 0)
return (~remainder); return (~remainder);
uint8_t c; uint8_t c;
for (uint32_t i = 0; i < length; ++i) { for (uint32_t i = 0; i < length; ++i) {
c = d[i]; c = d[i];
if (refin) c = reflect8(c); if (refin) c = reflect8(c);
// xor in at msb // xor in at msb
remainder ^= (c << 8); remainder ^= (c << 8);
// 8 iteration loop // 8 iteration loop
for (uint8_t j = 8; j; --j) { for (uint8_t j = 8; j; --j) {
if (remainder & 0x8000) { if (remainder & 0x8000) {
remainder = (remainder << 1) ^ polynomial; remainder = (remainder << 1) ^ polynomial;
@ -140,58 +140,58 @@ uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t pol
} }
} }
} }
if (refout) if (refout)
remainder = reflect16(remainder); remainder = reflect16(remainder);
return remainder; return remainder;
} }
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) { void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) {
// can't calc a crc on less than 1 byte // can't calc a crc on less than 1 byte
if ( n == 0 ) return; if ( n == 0 ) return;
init_table(ct); init_table(ct);
uint16_t crc = 0; uint16_t crc = 0;
switch (ct) { switch (ct) {
case CRC_14443_A: crc = crc16_a(d, n); break; case CRC_14443_A: crc = crc16_a(d, n); break;
case CRC_14443_B: case CRC_14443_B:
case CRC_15693: crc = crc16_x25(d, n); break; case CRC_15693: crc = crc16_x25(d, n); break;
case CRC_ICLASS: crc = crc16_iclass(d, n); break; case CRC_ICLASS: crc = crc16_iclass(d, n); break;
case CRC_FELICA:crc = crc16_xmodem(d, n); break; case CRC_FELICA:crc = crc16_xmodem(d, n); break;
//case CRC_LEGIC: //case CRC_LEGIC:
case CRC_CCITT: crc = crc16_ccitt(d, n); break; case CRC_CCITT: crc = crc16_ccitt(d, n); break;
case CRC_KERMIT: crc = crc16_kermit(d, n); break; case CRC_KERMIT: crc = crc16_kermit(d, n); break;
default: break; default: break;
} }
*first = (crc & 0xFF); *first = (crc & 0xFF);
*second = ((crc >> 8) & 0xFF); *second = ((crc >> 8) & 0xFF);
} }
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) { uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return 0; if ( n < 3 ) return 0;
init_table(ct); init_table(ct);
switch (ct) { switch (ct) {
case CRC_14443_A: return crc16_a(d, n); case CRC_14443_A: return crc16_a(d, n);
case CRC_14443_B: case CRC_14443_B:
case CRC_15693: return crc16_x25(d, n); case CRC_15693: return crc16_x25(d, n);
case CRC_ICLASS: return crc16_iclass(d, n); case CRC_ICLASS: return crc16_iclass(d, n);
case CRC_FELICA: return crc16_xmodem(d, n); case CRC_FELICA: return crc16_xmodem(d, n);
//case CRC_LEGIC: //case CRC_LEGIC:
case CRC_CCITT: return crc16_ccitt(d, n); case CRC_CCITT: return crc16_ccitt(d, n);
case CRC_KERMIT: return crc16_kermit(d, n); case CRC_KERMIT: return crc16_kermit(d, n);
default: break; default: break;
} }
return 0; return 0;
} }
// check CRC // check CRC
// ct crc type // ct crc type
// d buffer with data // d buffer with data
// n length (including crc) // n length (including crc)
// //
// This function uses the message + crc bytes in order to compare the "residue" afterwards. // This function uses the message + crc bytes in order to compare the "residue" afterwards.
// crc16 algos like CRC-A become 0x000 // crc16 algos like CRC-A become 0x000
@ -199,39 +199,39 @@ uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
// If calculated with crc bytes, the residue should be 0xF0B8 // If calculated with crc bytes, the residue should be 0xF0B8
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes) // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return false; if ( n < 3 ) return false;
init_table(ct); init_table(ct);
switch (ct) { switch (ct) {
case CRC_14443_A: return (crc16_a(d, n) == 0); case CRC_14443_A: return (crc16_a(d, n) == 0);
case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK); case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK);
case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK); case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK);
case CRC_ICLASS: return (crc16_iclass(d, n) == 0); case CRC_ICLASS: return (crc16_iclass(d, n) == 0);
case CRC_FELICA: return (crc16_xmodem(d, n) == 0); case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
//case CRC_LEGIC: //case CRC_LEGIC:
case CRC_CCITT: return (crc16_ccitt(d, n) == 0); case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
default: break; default: break;
} }
return false; return false;
} }
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE" // poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
uint16_t crc16_ccitt(uint8_t const *d, size_t n) { uint16_t crc16_ccitt(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0xffff, false, false); return crc16_fast(d, n, 0xffff, false, false);
} }
// FDX-B ISO11784/85) uses KERMIT // FDX-B ISO11784/85) uses KERMIT
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" // poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
uint16_t crc16_kermit(uint8_t const *d, size_t n) { uint16_t crc16_kermit(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x0000, true, true); return crc16_fast(d, n, 0x0000, true, true);
} }
// FeliCa uses XMODEM // FeliCa uses XMODEM
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM" // poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
uint16_t crc16_xmodem(uint8_t const *d, size_t n) { uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x0000, false, false); return crc16_fast(d, n, 0x0000, false, false);
} }
// Following standards uses X-25 // Following standards uses X-25
@ -240,14 +240,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
// ISO/IEC 13239 (formerly ISO/IEC 3309) // ISO/IEC 13239 (formerly ISO/IEC 3309)
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25" // poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
uint16_t crc16_x25(uint8_t const *d, size_t n) { uint16_t crc16_x25(uint8_t const *d, size_t n) {
uint16_t crc = crc16_fast(d, n, 0xffff, true, true); uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
crc = ~crc; crc = ~crc;
return crc; return crc;
} }
// CRC-A (14443-3) // CRC-A (14443-3)
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A" // poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
uint16_t crc16_a(uint8_t const *d, size_t n) { uint16_t crc16_a(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0xC6C6, true, true); return crc16_fast(d, n, 0xC6C6, true, true);
} }
// iClass crc // iClass crc
@ -255,12 +255,12 @@ uint16_t crc16_a(uint8_t const *d, size_t n) {
// poly 0x1021 reflected 0x8408 // poly 0x1021 reflected 0x8408
// poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS" // poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS"
uint16_t crc16_iclass(uint8_t const *d, size_t n) { uint16_t crc16_iclass(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x4807, true, true); return crc16_fast(d, n, 0x4807, true, true);
} }
// This CRC-16 is used in Legic Advant systems. // This CRC-16 is used in Legic Advant systems.
// poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC" // poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) { uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
uint16_t initial = uidcrc << 8 | uidcrc; uint16_t initial = uidcrc << 8 | uidcrc;
return crc16_fast(d, n, initial, true, true); return crc16_fast(d, n, initial, true, true);
} }

View file

@ -14,20 +14,20 @@
#define CRC16_POLY_CCITT 0x1021 #define CRC16_POLY_CCITT 0x1021
#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 #define CRC16_POLY_LEGIC 0xc6c6 //0x6363
#define CRC16_POLY_DNP 0x3d65 #define CRC16_POLY_DNP 0x3d65
#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc #define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
typedef enum { typedef enum {
CRC_NONE, CRC_NONE,
CRC_14443_A, CRC_14443_A,
CRC_14443_B, CRC_14443_B,
CRC_15693, CRC_15693,
CRC_ICLASS, CRC_ICLASS,
CRC_FELICA, CRC_FELICA,
CRC_LEGIC, CRC_LEGIC,
CRC_CCITT, CRC_CCITT,
CRC_KERMIT, CRC_KERMIT,
} CrcType_t; } CrcType_t;
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ); uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );

View file

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

View file

@ -1,9 +1,9 @@
#include "proxmark3.h" #include "proxmark3.h"
/* This is the default version.c file that Makefile.common falls back to if perl is not available */ /* This is the default version.c file that Makefile.common falls back to if perl is not available */
const struct version_information __attribute__((section(".version_information"))) version_information = { const struct version_information __attribute__((section(".version_information"))) version_information = {
VERSION_INFORMATION_MAGIC, VERSION_INFORMATION_MAGIC,
1, /* version 1 */ 1, /* version 1 */
0, /* version information not present */ 0, /* version information not present */
2, /* cleanliness couldn't be determined */ 2, /* cleanliness couldn't be determined */
/* Remaining fields: zero */ /* Remaining fields: zero */
}; };

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -22,7 +22,7 @@ void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
uint8_t b; uint8_t b;
uint16_t crc = CrcType; uint16_t crc = CrcType;
do { do {
b = *data++; b = *data++;
UpdateCrc14443(b, &crc); UpdateCrc14443(b, &crc);
} while (--length); } while (--length);
@ -36,10 +36,10 @@ void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
} }
bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) { bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) {
if (length < 3) return false; if (length < 3) return false;
uint8_t b1, b2; uint8_t b1, b2;
ComputeCrc14443(CrcType, data, length - 2, &b1, &b2); ComputeCrc14443(CrcType, data, length - 2, &b1, &b2);
if ((b1 == data[length - 2]) && (b2 == data[length - 1])) if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
return true; return true;
return false; return false;
} }

View file

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

View file

@ -17,58 +17,58 @@
#include "crc16.h" #include "crc16.h"
// REQUEST FLAGS // REQUEST FLAGS
#define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK) #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
#define ISO15_REQ_SUBCARRIER_TWO 0x01 // Tag should respond using two subcarriers (FSK) #define ISO15_REQ_SUBCARRIER_TWO 0x01 // Tag should respond using two subcarriers (FSK)
#define ISO15_REQ_DATARATE_LOW 0x00 // Tag should respond using low data rate #define ISO15_REQ_DATARATE_LOW 0x00 // Tag should respond using low data rate
#define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
#define ISO15_REQ_NONINVENTORY 0x00 #define ISO15_REQ_NONINVENTORY 0x00
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags #define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
#define ISO15_REQ_PROTOCOL_NONEXT 0x00 #define ISO15_REQ_PROTOCOL_NONEXT 0x00
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU #define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
// REQUEST FLAGS when INVENTORY is not set // REQUEST FLAGS when INVENTORY is not set
#define ISO15_REQ_SELECT 0x10 // only selected cards response #define ISO15_REQ_SELECT 0x10 // only selected cards response
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address #define ISO15_REQ_ADDRESS 0x20 // this req contains an address
#define ISO15_REQ_OPTION 0x40 // Command specific option selector #define ISO15_REQ_OPTION 0x40 // Command specific option selector
//REQUEST FLAGS when INVENTORY is set //REQUEST FLAGS when INVENTORY is set
#define ISO15_REQINV_AFI 0x10 // AFI Field is present #define ISO15_REQINV_AFI 0x10 // AFI Field is present
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot #define ISO15_REQINV_SLOT1 0x20 // 1 Slot
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots #define ISO15_REQINV_SLOT16 0x00 // 16 Slots
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector #define ISO15_REQINV_OPTION 0x40 // Command specific option selector
//RESPONSE FLAGS //RESPONSE FLAGS
#define ISO15_RES_ERROR 0x01 #define ISO15_RES_ERROR 0x01
#define ISO15_RES_EXT 0x08 // Protocol Extention #define ISO15_RES_EXT 0x08 // Protocol Extention
// RESPONSE ERROR CODES // RESPONSE ERROR CODES
#define ISO15_NOERROR 0x00 #define ISO15_NOERROR 0x00
#define ISO15_ERROR_CMD_NOT_SUP 0x01 // Command not supported #define ISO15_ERROR_CMD_NOT_SUP 0x01 // Command not supported
#define ISO15_ERROR_CMD_NOT_REC 0x02 // Command not recognized (eg. parameter error) #define ISO15_ERROR_CMD_NOT_REC 0x02 // Command not recognized (eg. parameter error)
#define ISO15_ERROR_CMD_OPTION 0x03 // Command option not supported #define ISO15_ERROR_CMD_OPTION 0x03 // Command option not supported
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error #define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10 #define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again #define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed #define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful #define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful #define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
// COMMAND CODES // COMMAND CODES
#define ISO15_CMD_INVENTORY 0x01 #define ISO15_CMD_INVENTORY 0x01
#define ISO15_CMD_STAYQUIET 0x02 #define ISO15_CMD_STAYQUIET 0x02
#define ISO15_CMD_READ 0x20 #define ISO15_CMD_READ 0x20
#define ISO15_CMD_WRITE 0x21 #define ISO15_CMD_WRITE 0x21
#define ISO15_CMD_LOCK 0x22 #define ISO15_CMD_LOCK 0x22
#define ISO15_CMD_READMULTI 0x23 #define ISO15_CMD_READMULTI 0x23
#define ISO15_CMD_WRITEMULTI 0x24 #define ISO15_CMD_WRITEMULTI 0x24
#define ISO15_CMD_SELECT 0x25 #define ISO15_CMD_SELECT 0x25
#define ISO15_CMD_RESET 0x26 #define ISO15_CMD_RESET 0x26
#define ISO15_CMD_WRITEAFI 0x27 #define ISO15_CMD_WRITEAFI 0x27
#define ISO15_CMD_LOCKAFI 0x28 #define ISO15_CMD_LOCKAFI 0x28
#define ISO15_CMD_WRITEDSFID 0x29 #define ISO15_CMD_WRITEDSFID 0x29
#define ISO15_CMD_LOCKDSFID 0x2A #define ISO15_CMD_LOCKDSFID 0x2A
#define ISO15_CMD_SYSINFO 0x2B #define ISO15_CMD_SYSINFO 0x2B
#define ISO15_CMD_SECSTATUS 0x2C #define ISO15_CMD_SECSTATUS 0x2C
char* Iso15693sprintUID(char *target, uint8_t *uid); char* Iso15693sprintUID(char *target, uint8_t *uid);
@ -78,49 +78,49 @@ char* Iso15693sprintUID(char *target, uint8_t *uid);
// Mode: highspeed && one subcarrier (ASK) // Mode: highspeed && one subcarrier (ASK)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// The sampling rate is 106.353 ksps/s, for T = 18.8 us // The sampling rate is 106.353 ksps/s, for T = 18.8 us
// SOF defined as // SOF defined as
// 1) Unmodulated time of 56.64us // 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz // 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz) // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
static const int Iso15693FrameSOF[] = { static const int Iso15693FrameSOF[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1 1, 1, 1, 1
}; };
static const int Iso15693Logic0[] = { static const int Iso15693Logic0[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1 -1, -1, -1, -1
}; };
static const int Iso15693Logic1[] = { static const int Iso15693Logic1[] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1 1, 1, 1, 1
}; };
// EOF defined as // EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us) // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz // 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us // 3) Unmodulated time of 56.64us
static const int Iso15693FrameEOF[] = { static const int Iso15693FrameEOF[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
}; };
#endif #endif

View file

@ -11,13 +11,13 @@ ms of the GNU GPL, version 2 or,
/* AT91SAM7S256 has 256k Flash and 64k RAM */ /* AT91SAM7S256 has 256k Flash and 64k RAM */
/* AT91SAM7S512 has 512k Flash and 64k RAM */ /* AT91SAM7S512 has 512k Flash and 64k RAM */
MEMORY MEMORY
{ {
bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */ bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */
bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */ bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */
osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */ osimage : ORIGIN = 0x00102000, LENGTH = 512K - 0x2000 /* Place where the main OS will end up */
ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */ ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */ commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
} }
/* Export some information that can be used from within the firmware */ /* Export some information that can be used from within the firmware */

View file

@ -13,9 +13,9 @@
// c keeps track on which step the prng is. // c keeps track on which step the prng is.
// legic_prng_get_bit() = gets a bit muxed from a and b. // legic_prng_get_bit() = gets a bit muxed from a and b.
struct lfsr { struct lfsr {
uint8_t a; uint8_t a;
uint8_t b; uint8_t b;
uint32_t c; uint32_t c;
} lfsr; } lfsr;
// Normal init is set following variables with a random value IV // Normal init is set following variables with a random value IV
@ -28,38 +28,38 @@ struct lfsr {
// which is used in the initialisation phase sending the IV // which is used in the initialisation phase sending the IV
// //
void legic_prng_init(uint8_t iv) { void legic_prng_init(uint8_t iv) {
lfsr.a = iv; lfsr.a = iv;
lfsr.b = 0; // hack to get a always 0 keystream lfsr.b = 0; // hack to get a always 0 keystream
lfsr.c = 0; lfsr.c = 0;
if(iv) if(iv)
lfsr.b = (iv << 1) | 1; lfsr.b = (iv << 1) | 1;
} }
void legic_prng_forward(int count) { void legic_prng_forward(int count) {
if (count == 0) return; if (count == 0) return;
lfsr.c += count; lfsr.c += count;
while(count--) { while(count--) {
// According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437 // According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
lfsr.a = (lfsr.a >> 1 | (lfsr.a ^ lfsr.a >> 6) << 6) & 0x7F; lfsr.a = (lfsr.a >> 1 | (lfsr.a ^ lfsr.a >> 6) << 6) & 0x7F;
lfsr.b = lfsr.b >> 1 | (lfsr.b ^ lfsr.b >> 2 ^ lfsr.b >> 3 ^ lfsr.b >> 7) << 7; lfsr.b = lfsr.b >> 1 | (lfsr.b ^ lfsr.b >> 2 ^ lfsr.b >> 3 ^ lfsr.b >> 7) << 7;
} }
} }
uint32_t legic_prng_count() { uint32_t legic_prng_count() {
return lfsr.c; return lfsr.c;
} }
uint8_t legic_prng_get_bit() { uint8_t legic_prng_get_bit() {
uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) ); uint8_t idx = 7 - ( (lfsr.a & 4) | (lfsr.a >> 2 & 2) | (lfsr.a >> 4 & 1) );
return lfsr.b >> idx & 1; return lfsr.b >> idx & 1;
} }
uint32_t legic_prng_get_bits(uint8_t len){ uint32_t legic_prng_get_bits(uint8_t len){
uint32_t a = 0; uint32_t a = 0;
for(uint8_t i = 0; i < len; ++i) { for(uint8_t i = 0; i < len; ++i) {
a |= legic_prng_get_bit() << i; a |= legic_prng_get_bit() << i;
legic_prng_forward(1); legic_prng_forward(1);
} }
return a; return a;
} }

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
#include <stdlib.h> // for #include <stdlib.h> // for
#include <stdbool.h> // for bool #include <stdbool.h> // for bool
#include "parity.h" // for parity test #include "parity.h" // for parity test
#include "util.h" // for ARRAYLEN #include "util.h" // for ARRAYLEN
//might not be high enough for noisy environments //might not be high enough for noisy environments
#define NOISE_AMPLITUDE_THRESHOLD 10 #define NOISE_AMPLITUDE_THRESHOLD 10
@ -30,11 +30,11 @@
//generic //generic
typedef struct { typedef struct {
int low; int low;
int high; int high;
int mean; int mean;
int amplitude; int amplitude;
bool isnoise; bool isnoise;
} signal_t; } signal_t;
signal_t* getSignalProperties(void); signal_t* getSignalProperties(void);
@ -50,12 +50,12 @@ extern int askdemod(uint8_t *bits, size_t *size, int *clk, int *invert, int
extern int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx); extern int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType, int *startIdx);
extern void askAmp(uint8_t *bits, size_t size); extern void askAmp(uint8_t *bits, size_t size);
extern int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert); extern int BiphaseRawDecode(uint8_t *bits, size_t *size, int *offset, int invert);
extern uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest); extern uint8_t bits_to_array(const uint8_t *bits, size_t size, uint8_t *dest);
extern uint32_t bytebits_to_byte(uint8_t *src, size_t numbits); extern uint32_t bytebits_to_byte(uint8_t *src, size_t numbits);
extern uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits); extern uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits);
extern uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj); extern uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj);
extern int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr); extern int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr);
extern bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low); extern bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low);
extern uint8_t detectFSKClk(uint8_t *bits, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge); extern uint8_t detectFSKClk(uint8_t *bits, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge);
extern int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx); extern int DetectNRZClock(uint8_t *dest, size_t size, int clock, size_t *clockStartIdx);
extern int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc); extern int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc);
@ -69,8 +69,8 @@ extern int ManchesterEncode(uint8_t *bits, size_t size);
extern int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos); extern int manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alignPos);
extern int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx); extern int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
extern bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); extern bool preambleSearch(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
extern bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone); extern bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone);
extern int pskRawDemod(uint8_t *dest, size_t *size, int *clock, int *invert); extern int pskRawDemod(uint8_t *dest, size_t *size, int *clock, int *invert);
extern int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *startIdx); extern int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *startIdx);
extern void psk2TOpsk1(uint8_t *bits, size_t size); extern void psk2TOpsk1(uint8_t *bits, size_t size);

View file

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

View file

@ -17,7 +17,7 @@ uint32_t burtle_get_mod( prng_ctx *x ) {
void burtle_init_mod(prng_ctx *x, uint32_t seed ) { void burtle_init_mod(prng_ctx *x, uint32_t seed ) {
x->a = 0xf1ea5eed; x->a = 0xf1ea5eed;
x->b = x->c = x->d = seed; x->b = x->c = x->d = seed;
for (uint8_t i=0; i < 42; ++i) { for (uint8_t i=0; i < 42; ++i) {
(void)burtle_get_mod(x); (void)burtle_get_mod(x);
} }
@ -33,7 +33,7 @@ void burtle_init(prng_ctx *x, uint32_t seed ) {
uint32_t GetSimplePrng( uint32_t seed ){ uint32_t GetSimplePrng( uint32_t seed ){
seed *= 0x19660D; seed *= 0x19660D;
seed += 0x3C6EF35F; seed += 0x3C6EF35F;
return seed; return seed;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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), // takes a array of binary values, start position, length of bits per parity (includes parity bit),
// Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run) // Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run)
size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) { size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) {
uint32_t parityWd = 0; uint32_t parityWd = 0;
size_t j = 0, bitcount = 0; size_t j = 0, bitcount = 0;
for (int word = 0; word < (bLen); word += pLen){ for (int word = 0; word < (bLen); word += pLen){
for (int bit = 0; bit < pLen; ++bit){ for (int bit = 0; bit < pLen; ++bit){
parityWd = (parityWd << 1) | bitstream[startIdx+word+bit]; parityWd = (parityWd << 1) | bitstream[startIdx+word+bit];
bitstream[j++] = (bitstream[startIdx + word + bit]); bitstream[j++] = (bitstream[startIdx + word + bit]);
} }
j--; // overwrite parity with next data j--; // overwrite parity with next data
// if parity fails then return 0 // if parity fails then return 0
switch (pType) { switch (pType) {
case 3: if (bitstream[j] == 1) return 0; break; //should be 0 spacer bit case 3: if (bitstream[j] == 1) return 0; break; //should be 0 spacer bit
case 2: if (bitstream[j] == 0) return 0; break; //should be 1 spacer bit case 2: if (bitstream[j] == 0) return 0; break; //should be 1 spacer bit
default: //test parity default: //test parity
if (parityTest(parityWd, pLen, pType) == 0) return 0; break; if (parityTest(parityWd, pLen, pType) == 0) return 0; break;
} }
bitcount += ( pLen - 1 ); bitcount += ( pLen - 1 );
parityWd = 0; parityWd = 0;
} }
// if we got here then all the parities passed // if we got here then all the parities passed
//return ID start index and size //return ID start index and size
return bitcount; return bitcount;
} }
@ -76,28 +76,28 @@ size_t removeParity(uint8_t *bitstream, size_t startIdx, uint8_t pLen, uint8_t p
*/ */
size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType) size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType)
{ {
uint32_t parityWd = 0; uint32_t parityWd = 0;
size_t j = 0, bitCnt = 0; size_t j = 0, bitCnt = 0;
for (int word = 0; word < sourceLen; word += pLen-1) { for (int word = 0; word < sourceLen; word += pLen-1) {
for (int bit = 0; bit < pLen-1; ++bit){ for (int bit = 0; bit < pLen-1; ++bit){
parityWd = (parityWd << 1) | bits[word+bit]; parityWd = (parityWd << 1) | bits[word+bit];
dest[j++] = (bits[word+bit]); dest[j++] = (bits[word+bit]);
} }
// if parity fails then return 0 // if parity fails then return 0
switch (pType) { switch (pType) {
case 3: dest[j++] = 0; break; // marker bit which should be a 0 case 3: dest[j++] = 0; break; // marker bit which should be a 0
case 2: dest[j++] = 1; break; // marker bit which should be a 1 case 2: dest[j++] = 1; break; // marker bit which should be a 1
default: default:
dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1; dest[j++] = parityTest(parityWd, pLen-1, pType) ^ 1;
break; break;
} }
bitCnt += pLen; bitCnt += pLen;
parityWd = 0; parityWd = 0;
} }
// if we got here then all the parities passed // if we got here then all the parities passed
//return ID start index and size //return ID start index and size
return bitCnt; return bitCnt;
} }
// by marshmellow // by marshmellow
@ -110,18 +110,18 @@ size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen,
*/ */
void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) { void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) {
// Copy to destination, shifted one step to make room for EVEN parity // Copy to destination, shifted one step to make room for EVEN parity
memcpy(dest+1, source, length); memcpy(dest+1, source, length);
// half length, Even and Odd is calculated to the middle. // half length, Even and Odd is calculated to the middle.
uint8_t len_h2 = length >> 1; uint8_t len_h2 = length >> 1;
// add EVEN parity at the beginning // add EVEN parity at the beginning
*(dest) = GetParity(source, EVEN, len_h2); *(dest) = GetParity(source, EVEN, len_h2);
dest += length + 1; dest += length + 1;
// add ODD parity at the very end // add ODD parity at the very end
*(dest) = GetParity(source + len_h2, ODD, len_h2); *(dest) = GetParity(source + len_h2, ODD, len_h2);
} }
@ -138,18 +138,18 @@ void wiegand_add_parity(uint8_t *source, uint8_t *dest, uint8_t len) {
*/ */
void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){ void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
uint8_t data[MAX_BITS_TXX55] = {0}; uint8_t data[MAX_BITS_TXX55] = {0};
memset(data, 0, sizeof(data)); memset(data, 0, sizeof(data));
num_to_wiegand_bits(oem, fc, cn, data, formatlen); num_to_wiegand_bits(oem, fc, cn, data, formatlen);
// loop // loop
// (formatlen / 32 ) + 1 // (formatlen / 32 ) + 1
// (formatlen >> 5) + 1 // (formatlen >> 5) + 1
for (int i = 0; i < formatlen ; ++i){ for (int i = 0; i < formatlen ; ++i){
uint32_t value = bytebits_to_byte( data + (i * 32), 32); uint32_t value = bytebits_to_byte( data + (i * 32), 32);
num_to_bytes(value, 32, dest + (i*4) ); num_to_bytes(value, 32, dest + (i*4) );
} }
} }
/* /*
@ -162,70 +162,70 @@ void num_to_wiegand_bytes(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest,
*/ */
void num_to_wiegand_bits(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){ void num_to_wiegand_bits(uint64_t oem, uint64_t fc, uint64_t cn, uint8_t *dest, uint8_t formatlen){
uint8_t bits[MAX_BITS_TXX55] = {0}; uint8_t bits[MAX_BITS_TXX55] = {0};
memset(bits, 0, sizeof(bits)); memset(bits, 0, sizeof(bits));
uint8_t *temp = bits; uint8_t *temp = bits;
uint64_t value = 0; uint64_t value = 0;
switch ( formatlen ){ switch ( formatlen ){
case 26 : // 26bit HID H10301 case 26 : // 26bit HID H10301
fc &= 0xFF; // 8bits fc &= 0xFF; // 8bits
cn &= 0xFFFF; // 16bits cn &= 0xFFFF; // 16bits
value = fc << 16 | cn; value = fc << 16 | cn;
num_to_bytebits(value, 24, temp); num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24); wiegand_add_parity(temp, dest, 24);
break; break;
case 261: // 26bit Indala case 261: // 26bit Indala
fc &= 0xFFF; // 12bits fc &= 0xFFF; // 12bits
cn &= 0xFFF; // 12bits cn &= 0xFFF; // 12bits
value = fc << 12 | cn; value = fc << 12 | cn;
num_to_bytebits(value, 24, temp); num_to_bytebits(value, 24, temp);
wiegand_add_parity(temp, dest, 24); wiegand_add_parity(temp, dest, 24);
break; break;
case 34 : // 34bits HID case 34 : // 34bits HID
fc &= 0xFFFF; // 16bits fc &= 0xFFFF; // 16bits
cn &= 0xFFFF; // 16bits cn &= 0xFFFF; // 16bits
value = fc << 16 | cn; value = fc << 16 | cn;
num_to_bytebits(value, 32, temp); num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32); wiegand_add_parity(temp, dest, 32);
break; break;
case 35 : // 35bits HID case 35 : // 35bits HID
fc &= 0xFFF; // 12bits fc &= 0xFFF; // 12bits
cn &= 0xFFFFFF; // 20bits cn &= 0xFFFFFF; // 20bits
value = fc << 20 | cn; value = fc << 20 | cn;
num_to_bytebits(value, 32, temp); num_to_bytebits(value, 32, temp);
wiegand_add_parity(temp, dest, 32); wiegand_add_parity(temp, dest, 32);
break; break;
case 37 : // H10304 case 37 : // H10304
fc &= 0xFFFF; // 16bits fc &= 0xFFFF; // 16bits
cn &= 0x7FFFF; // 19bits cn &= 0x7FFFF; // 19bits
value = fc << 19 | cn; value = fc << 19 | cn;
num_to_bytebits(value, 35, temp); num_to_bytebits(value, 35, temp);
wiegand_add_parity(temp, dest, 35); wiegand_add_parity(temp, dest, 35);
break; break;
case 39 : // 39bit KERI System Pyramid case 39 : // 39bit KERI System Pyramid
fc &= 0x1FFFF; // 17bits fc &= 0x1FFFF; // 17bits
cn &= 0xFFFFFFFF; // 20bits cn &= 0xFFFFFFFF; // 20bits
value = fc << 20 | cn; value = fc << 20 | cn;
num_to_bytebits(value, 37, temp); num_to_bytebits(value, 37, temp);
wiegand_add_parity(temp, dest, 37); wiegand_add_parity(temp, dest, 37);
break; break;
case 44 : // 44bit KERI system Pyramid case 44 : // 44bit KERI system Pyramid
oem &= 0xFF; // 8bits oem &= 0xFF; // 8bits
fc &= 0xFFF; // 12bits fc &= 0xFFF; // 12bits
cn &= 0xFFFFFFFF; // 21bits cn &= 0xFFFFFFFF; // 21bits
value = oem << 20 | fc << 12 | cn; value = oem << 20 | fc << 12 | cn;
num_to_bytebits(value, 42, temp); num_to_bytebits(value, 42, temp);
wiegand_add_parity(temp, dest, 42); wiegand_add_parity(temp, dest, 42);
break; break;
case 50 : // AWID 50 RBH case 50 : // AWID 50 RBH
fc &= 0xFFFF; // 16bits fc &= 0xFFFF; // 16bits
cn &= 0xFFFFFFFF // 32bits cn &= 0xFFFFFFFF // 32bits
value = fc << 32 | cn; value = fc << 32 | cn;
num_to_bytebits(value, 48, temp); num_to_bytebits(value, 48, temp);
wiegand_add_parity(temp, dest, 48); // verify! wiegand_add_parity(temp, dest, 48); // verify!
break; break;
default: default:
break; break;
} }
} }