Proxmark3 community

Research, development and trades concerning the powerful Proxmark3 device.

Remember; sharing is caring. Bring something back to the community.


"Learn the tools of the trade the hard way." +Fravia

You are not logged in.

Announcement

Time changes and with it the technology
Proxmark3 @ discord

Users of this forum, please be aware that information stored on this site is not private.

#1 2010-02-19 19:18:37

atrox
Contributor
Registered: 2010-01-08
Posts: 35

iso15693 cards crashing proxmark3

current firmwares are crashing when using "hi15reader"/"hf 15 reader" with an iso15693 skidata card. they finish correctly when no card is in reading distance:

> hi15reader
#db# 0 octets read from IDENTIFY request: 0 0 0 0 0 0
#db# 0 octets read from SELECT request: 0 0 0 0 0 0 0
#db# 807415840 octets read from XXX request: 0 0 0 0

when a card is in vicinity:
> hi15reader
#db# 12 octets read from IDENTIFY request: 0 0 55 4e
proxmark3> read failed: No error(-19)!
Trying to reopen device...

i've tested this behavior with different skidata iso15k cards.

I remember older firmwares, worked fine.

Offline

#2 2010-02-19 20:23:13

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

By using binary search over the svn-versions I found the changes that breaks the iso15k support:

the last working version is svn-296.
svn-297 breaks the hi15reader.

http://code.google.com/p/proxmark3/source/detail?r=297
its most probably in the iso15693.c

Offline

#3 2010-02-19 20:39:23

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

since it looks like, the crash happens at the output of the read data, after all reading has been done, i suspect an usb-timing issue, similar to the losim-issue in http://www.proxmark.org/forum/post/2561/#p2561

Offline

#4 2010-02-20 10:50:04

adam@algroup.co.uk
Contributor
From: UK
Registered: 2009-05-01
Posts: 203
Website

Re: iso15693 cards crashing proxmark3

Hmmm.... This would then be a problem for all commands that send messages back using DbpString... It does look like it relies on timing, and would benefit from some synchronicity though!

        UsbSendPacket((BYTE *)&c, sizeof(c));
        // TODO fix USB so stupid things like this aren't req'd
        SpinDelay(50);


But it seems to work fine for me:

  proxmark3> hf 15 reader
  #db# 12 octets read from IDENTIFY request: 0 0 9d 89
  #db# 0 octets read from SELECT request: 0 0 0 0 0 0 0
  #db# 0 octets read from XXX request: 0 0 0 0 0 0 0 0

can you tweak the SpinDelay to something large and see if your problem goes away? If it does, I'll add an ACK/wait feature for prox->client communications...

Offline

#5 2010-02-20 11:52:28

iZsh
Contributor
Registered: 2010-01-02
Posts: 95

Re: iso15693 cards crashing proxmark3

Someone already implemented a ack/wait feature (maybe that was you? smile )
WaitForResponse(CMD_ACK);

Offline

#6 2010-02-20 13:15:13

adam@algroup.co.uk
Contributor
From: UK
Registered: 2009-05-01
Posts: 203
Website

Re: iso15693 cards crashing proxmark3

Yes, it was me but it's client->prox - we probably need to go the other way as well...

Offline

#7 2010-02-26 18:59:27

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

adam@algroup.co.uk wrote:

  proxmark3> hf 15 reader
  #db# 12 octets read from IDENTIFY request: 0 0 9d 89

this output is truncated after about 48 chars - according to the source, the arm sends 8 hex-bytes, but the rest is silently discarded/truncated.

newer svn revisions now also behave so on my device (means: no crashing, just truncating). after shortening the long text "octets read from IDENTIFY request: %x %x...." to something something like "o ID: %x %x..." i was able to get the other bytes too.

so its probably the same bug as http://www.proxmark.org/forum/topic/463 … ack-space/

Last edited by atrox (2010-02-26 22:00:02)

Offline

#8 2010-02-26 22:29:18

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

while I was fixing this issue, I also pimped the output and added a ReadSingleBlock(0..31) command - it now attempts to read memory pages from iso15693 cards and displays it as ascii/hexdump. I've used ReadSingleBlock commands and not the ReadMultiBlock command, because TagIt-Cards do not support them.

proxmark3> hf 15 reader
#db# 12 octets read from IDENTIFY request:
#db# NoErr CrcOK
#db# ..SEk..@ 00 00 53 45 6b 07 00 40
#db# ....     05 e0 0c e5
#db# UID = 53 45 6b 07 00 40 05
#db# 0 octets read from SELECT request:
#db# 4 octets read from XXX request:
#db# Error 01:notSupp CrcOK
#db# ....     01 01 16 07
#db# READ SINGLE BLOCK 0 returned 8 octets:
#db# NoErr CrcOK
#db# .....\.. 00 00 85 08 19 5c 14 a8
#db# READ SINGLE BLOCK 1 returned 8 octets:
#db# NoErr CrcOK
#db# ....` .. 00 00 82 18 60 20 97 e4

this is the diff for this:

--- armsrc/iso15693.c.345  2010-02-26 19:30:55.000000000 +0100
+++ armsrc/iso15693.c  2010-02-26 22:10:28.000000000 +0100
@@ -177,6 +177,87 @@
   return dest;
 }
 
+///////////////////////////////////////// hexdump
+
+void Dbhexdump(int len, BYTE *d) {
+  int l=0,i;
+  char ascii[9];
+
+  while (len>0) {
+    if (len>8) l=8;
+    else l=len;
+    
+    memcpy(ascii,d,l);
+    ascii[l]=0;  
+    
+    // filter safe ascii
+    for (i=0;i<l;i++) 
+      if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
+
+    Dbprintf("%-8s %*D",ascii,l,d," ");
+
+    len-=8;
+    d+=8;    
+  }
+
+}
+
+void DbdecodeIso15693Answer(int len, BYTE *d) {
+  char status[48]={0};
+  WORD crc;
+
+  if (len>3) {
+    if (d[0]&(1<<3)) 
+      strcat(status,"ProtExt ");
+    if (d[0]&1) { 
+      // error
+      strcat(status,"Error ");
+      switch (d[1]) {
+        case 0x01: 
+          strcat(status,"01:notSupp");
+          break;
+        case 0x02: 
+          strcat(status,"02:notRecog");
+          break;
+        case 0x03: 
+          strcat(status,"03:optNotSupp");
+          break;
+        case 0x0f: 
+          strcat(status,"0f:noInfo");
+          break;
+        case 0x10: 
+          strcat(status,"10:dontExist");
+          break;
+        case 0x11: 
+          strcat(status,"11:lockAgain");
+          break;
+        case 0x12: 
+          strcat(status,"12:locked");
+          break;
+        case 0x13: 
+          strcat(status,"13:progErr");
+          break;
+        case 0x14: 
+          strcat(status,"14:lockErr");
+          break;
+        default:
+          strcat(status,"unknownErr");
+      }
+      strcat(status," ");
+    } else {
+      strcat(status,"NoErr ");
+    }
+      
+    crc=Crc(d,len-2);
+    if ( (( crc & 0xff ) == d[len-2]) && (( crc >> 8 ) == d[len-1]) ) 
+      strcat(status,"CrcOK");
+    else
+      strcat(status,"CrcFail"); 
+
+    Dbprintf("%s",status);
+  }
+}
+
 ////////////////////////////////////////// code to do 'itoa'
 
 /* reverse:  reverse string s in place */
@@ -210,6 +291,7 @@
 
 //////////////////////////////////////// END 'itoa' CODE
 
+
 //-----------------------------------------------------------------------------
 // Encode (into the ToSend buffers) an identify request, which is the first
 // thing that you must send to a tag to get a response.
@@ -310,23 +392,23 @@
   // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block
   // followed by teh block data
   // one sub-carrier, inventory, 1 slot, fast rate
-  cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit
+  cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit
   // READ BLOCK command code
   cmd[1] = 0x20;
   // UID may be optionally specified here
   // 64-bit UID
-  cmd[2] = 0x32;
-  cmd[3]= 0x4b;
-  cmd[4] = 0x03;
-  cmd[5] = 0x01;
-  cmd[6] = 0x00;
-  cmd[7] = 0x10;
-  cmd[8] = 0x05;
+  cmd[2] = uid[0];
+  cmd[3] = uid[1];
+  cmd[4] = uid[2];
+  cmd[5] = uid[3];
+  cmd[6] = uid[4];
+  cmd[7] = uid[5];
+  cmd[8] = uid[6];
   cmd[9]= 0xe0; // always e0 (not exactly unique)
   // Block number to read
   cmd[10] = blockNumber;//0x00;
   //Now the CRC
-  crc = Crc(cmd, 11); // the crc needs to be calculated over 2 bytes
+  crc = Crc(cmd, 11); // the crc needs to be calculated over 12 bytes
   cmd[11] = crc & 0xff;
   cmd[12] = crc >> 8;
 
@@ -933,6 +1015,7 @@
   int answerLen1 = 0;
   int answerLen2 = 0;
   int answerLen3 = 0;
+  int i=0; // counter
 
   // Blank arrays
   memset(BigBuf + 3660, 0, 300);
@@ -1003,6 +1086,7 @@
     TagUID[6] = answer1[8]; // IC Manufacturer code
 
     // Now send the SELECT command
+    // since the SELECT command is optional, we should not rely on it.
     BuildSelectRequest(TagUID);
     TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  // No longer ToSendMax+3
     // Now wait for a response
@@ -1020,21 +1104,38 @@
 
   }
 
-  Dbprintf("%d octets read from IDENTIFY request: %x %x %x %x %x %x %x %x %x", answerLen1,
-    answer1[0], answer1[1], answer1[2],
-    answer1[3], answer1[4], answer1[5],
-    answer1[6], answer1[7], answer1[8]);
-
-  Dbprintf("%d octets read from SELECT request: %x %x %x %x %x %x %x %x %x", answerLen2,
-    answer2[0], answer2[1], answer2[2],
-    answer2[3], answer2[4], answer2[5],
-    answer2[6], answer2[7], answer2[8]);
-
-  Dbprintf("%d octets read from XXX request: %x %x %x %x %x %x %x %x %x", answerLen3,
-    answer3[0], answer3[1], answer3[2],
-    answer3[3], answer3[4], answer3[5],
-    answer3[6], answer3[7], answer3[8]);
-
+  Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
+  DbdecodeIso15693Answer(answerLen1,answer1);
+  Dbhexdump(answerLen1,answer1);
+
+  if (answerLen1>=12) 
+    Dbprintf("UID = %*D",7,TagUID," ");
+
+  Dbprintf("%d octets read from SELECT request:", answerLen2);
+  DbdecodeIso15693Answer(answerLen2,answer2);
+  Dbhexdump(answerLen2,answer2);
+
+  Dbprintf("%d octets read from XXX request:", answerLen3);
+  DbdecodeIso15693Answer(answerLen3,answer3);
+  Dbhexdump(answerLen3,answer3);
+
+
+  // read all pages
+  if (answerLen1>=12) {
+    i=0;      
+    while (i<32) {  // sanity check, assume max 32 pages
+      BuildReadBlockRequest(TagUID,i);
+                  TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  
+                  answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
+      if (answerLen2>0) {
+        Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
+        DbdecodeIso15693Answer(answerLen2,answer2);
+        Dbhexdump(answerLen2,answer2);
+        if ( *((DWORD*) answer2) == 0x07160101 ) break; // exit on NoPageErr 
+      } 
+      i++;
+    } 
+  }
 
 //  str2[0]=0;
 //  for(i = 0; i < responseLen3; i++) {

btw, there is some more to be done here, since a lot of the functions use hard coded UID here ... but one step at a time.

Offline

#9 2010-02-26 22:53:34

iZsh
Contributor
Registered: 2010-01-02
Posts: 95

Re: iso15693 cards crashing proxmark3

I don't want to sound ungrateful, but since we're trying hard to clean the code, could you read the new HACKING.txt file to have a compliant patch ? wink

As a side comment, for Dbhexdump() I would suggest creating a new file dbg.h, debug.h, or proxdebug.h or something along those names, to put dbg_hexdump() along with dbg_string and dbg_printf (that we should move away from appmain.c) in there.

Offline

#10 2010-02-26 23:26:16

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

I agree on putting all the candy output functions to some separate file is a good idea.
that would need some kind of a major makeover of the iso15693.c, which I was to humble to suggest on my first implemented feature. :-) *g*

Offline

#11 2010-03-11 14:41:04

doob
Member
Registered: 2008-07-21
Posts: 15

Re: iso15693 cards crashing proxmark3

I'm sorry my bad, i bashed out 15693 very quickly to support an urgent requirement and never got round to coming back and finishing off.

I've had to step back, partly because I'm so busy and partly because I can't figure out what's happening with the codebase at the moment.

Offline

#12 2010-03-11 18:09:37

*dudux
Member
Registered: 2009-10-04
Posts: 7

Re: iso15693 cards crashing proxmark3

atrox wrote:

current firmwares are crashing when using "hi15reader"/"hf 15 reader" with an iso15693 skidata card. they finish correctly when no card is in reading distance:

> hi15reader
#db# 0 octets read from IDENTIFY request: 0 0 0 0 0 0
#db# 0 octets read from SELECT request: 0 0 0 0 0 0 0
#db# 807415840 octets read from XXX request: 0 0 0 0

when a card is in vicinity:
> hi15reader
#db# 12 octets read from IDENTIFY request: 0 0 55 4e
proxmark3> read failed: No error(-19)!
Trying to reopen device...

i've tested this behavior with different skidata iso15k cards.

I remember older firmwares, worked fine.

Hi, When I've tried those commands, I got other errors output:

guepardo linux # ./proxmark3
proxmark3> hi15read
> hi15read
proxmark3> hisamples
> hisamples
proxmark3> hi15demod
> hi15demod
SOF at 64, correlation 0
EOF at 128
error, uneven octet! (discard extra bits!)
   mask=10
1 octets
#  0: 26
CRC=0000
proxmark3>

Sometimes it want work fine and all is normal:

> buffclear                                         
#db# Buffer cleared                                 
> hi15read                                          
> hisamples                                         
> hi15demod                                         
SOF at 35, correlation 21                           
EOF at 435                                          
12 octets                                           
#  0: 00                                            
#  1: 00                                            
#  2: 41                                            
#  3: 2d
#  4: fc
#  5: 1b
#  6: 00
#  7: 01
#  8: 04
#  9: e0
# 10: b3
# 11: 12
CRC=12b3

I am running pm3-20090713-r52,because i will buy px3 in January 2010

P.d. me too is skidata!!

Last edited by *dudux (2010-03-11 18:16:40)

Offline

#13 2010-04-20 15:37:05

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

ok i looked into the is15693 code, and there is a lot to be done - besides, that the UID is hardcoded in a number of places - it supports only 1 of 2 reader->tag communication modes (the so called 1-out-of-4 mode), and 1 of 4 tag->reader modes (high speed, one subcarrier). as long as you read only fully iso15693 compatible tags, that is ok, but not all tags are. and for sniffing we likely miss everything, since there is only a chance of 1 out of 4 to decode it.

I like to contribute those modes and to add commands for reading and writing memory pages or calling other functions - but, according to izsh's post, source inclusion policy seemed to got very strict lately. Especially the spaces_as_underscores rule for function names demands a major refactoring of all sourcecode i need to touch (or did i got this wrong?) - this is especially remarkable since the major portion of the code so far uses CamelCase notation. Don't expect me to be holier than the pope, when everthing else isn't.
I'd like to contribute and I will adopt to your code policy, but I can not do all the major makeovers too.

Last edited by atrox (2010-04-21 11:28:31)

Offline

#14 2010-09-27 01:18:14

atrox
Contributor
Registered: 2010-01-08
Posts: 35

Re: iso15693 cards crashing proxmark3

here is my code for reading and writing iso15693 tags and do some other things more. Basically I wrote a new command layer that allows the client to communicate directly with a tag. I've also re-factored the old code to better fit the code guidelines, added the 1of256 transmission mode and tried to tweak it, to be more error resistant.

http://code.google.com/p/proxmark3/issues/detail?id=20

Offline

#15 2010-09-27 09:14:26

proxcat
Contributor
Registered: 2008-11-28
Posts: 62
Website

Re: iso15693 cards crashing proxmark3

nice work!

Offline

#16 2010-09-28 14:01:56

notserpe
Member
From: Montreal
Registered: 2009-09-15
Posts: 14
Website

Re: iso15693 cards crashing proxmark3

I second the nice work!
I just tested the patch against HEAD and successfully
read a bunch of Tag-It HF-I Plus tags I have lying around.

Offline

#17 2010-09-29 09:06:23

rumpeltux
Contributor
From: München, Germany
Registered: 2010-02-04
Posts: 18
Website

Re: iso15693 cards crashing proxmark3

I also submitted a patch ealier to adam concerning to USB inconsistancies, but apparently this did not yet get integrated. I’m not an expert on USB protocols so reviews are appreciated.
Anyways for those who want to try (works very well for me wink):

From: Hagen Fritsch <…>
Date: Wed, 14 Jul 2010 11:31:46 +0200
Subject: [PATCH] usb: (hopefully) fix usb and remove spin delays

---
 armsrc/appmain.c |   21 ---------------------
 common/usb.c     |   15 +++++++++------
 2 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index ba50df8..ddf8ad1 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -89,29 +89,8 @@ void DbpString(char *str)
   memcpy(c.d.asBytes, str, c.arg[0]);
 
   UsbSendPacket((uint8_t *)&c, sizeof(c));
-  // TODO fix USB so stupid things like this aren't req'd
-  SpinDelay(50);
 }
 
-#if 0
-void DbpIntegers(int x1, int x2, int x3)
-{
-  /* this holds up stuff unless we're connected to usb */
-  if (!UsbConnected())
-    return;
-
-  UsbCommand c;
-  c.cmd = CMD_DEBUG_PRINT_INTEGERS;
-  c.arg[0] = x1;
-  c.arg[1] = x2;
-  c.arg[2] = x3;
-
-  UsbSendPacket((uint8_t *)&c, sizeof(c));
-  // XXX
-  SpinDelay(50);
-}
-#endif
-
 void Dbprintf(const char *fmt, ...) {
 // should probably limit size here; oh well, let's just use a big buffer
   char output_string[128];
diff --git a/common/usb.c b/common/usb.c
index 3f30d97..de5e99e 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -399,14 +399,17 @@ void UsbSendPacket(uint8_t *packet, int len)
     for(i = 0; i < thisTime; i++) {
       AT91C_BASE_UDP->UDP_FDR[2] = packet[i];
     }
-    AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
 
-    while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP))
-      ;
-    AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
+    /* clear any pending TX complete flag */
+    if(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
+      AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
+      while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) ;
+    }
 
-    while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)
-      ;
+    AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
+
+    /* now wait for the TX complete */
+    while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP))  ;
 
     len -= thisTime;
     packet += thisTime;

Offline

Board footer

Powered by FluxBB