Writing to Mifare Ultralight C with PN532 library for Arduino Uno - nfc

I use the sample code to read from MIFARE Ultralight and write to MIFARE Classic, with the definition in .h file:
#define PN532_RESPONSE_INDATAEXCHANGE (0x41)
#define MIFARE_CMD_WRITE (0xA0)
but when I run the code below:
/**************************************************************************/
uint8_t PN532::mifareultralight_WritePage (uint8_t page, uint8_t *buffer1)
{
/* Prepare the first command */
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
pn532_packetbuffer[1] = 1; /* Card number */
pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
memcpy (pn532_packetbuffer + 4, buffer1, 4); /* Data Payload */
/* Send the command */
if (HAL(writeCommand)(pn532_packetbuffer, 8)) {
Serial.println(F("Go here 1"));
return 0;
}
Serial.println(F("Go here 2"));
/* Read the response packet */
return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
}
The result would be like this:
Scan a NFC tag
write: 4A 1 0
read: 4B 1 1 0 44 0 7 4 C1 37 CA 2C 2C 80
ATQA: 0x 44SAK: 0x 0
Writing Mifare Ultralight
write: 40 1 30 4
read: 41 0 2 0 0 10 0 6 1 10 11 FF 0 0 0 0 0 0
write: 40 1 30 3
read: 41 0 0 0 0 0 2 0 0 10 0 6 1 10 11 FF 0 0
Tag capacity 0 bytes
write: 40 1 A0 5 1 2 3 4
Go here 2
Write failed 0
It does not go into "Go here 1", it means that no write command to the reader, do anyone know why?

That write command you are using seems to be wrong. You are using the COMPATIBILITY_WRITE command code (0xA0) but you pass the parameters of a WRITE command.
I suggest you stick to the WRITE command:
+-----------+------+------+---------------------+
| WRAPPING | CMD | ADDR | DATA (1 PAGE) |
+-----------+------+------+---------------------+
| 0x40 0x01 | 0xA2 | 0x05 | 0x01 0x02 0x03 0x04 |
+-----------+------+------+---------------------+
Or you could also use the COMPATIBILITY_WRITE command:
You start with sending the command and the address:
+-----------+------+------+
| WRAPPING | CMD | ADDR |
+-----------+------+------+
| 0x40 0x01 | 0xA0 | 0x05 |
+-----------+------+------+
You should then receive the ACK/NAK status from the tag.
Then you send the data in a second frame:
+-----------+---------------------+------------------------------------------------------------+
| WRAPPING | DATA (1 PAGE) | FILLER (3 EMPTY PAGES)
+-----------+---------------------+------------------------------------------------------------+
| 0x40 0x01 | 0x01 0x02 0x03 0x04 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+-----------+---------------------+------------------------------------------------------------+

Related

ATQA in Mifare and RFU configurations

I received some cards that are supposed to be Mifare Classic cards.
When I perform the level 1 of anticollision (REQA) the ATQA is 04 00.
According to ISO/IEC 14443-3, the first byte of the ATQA is RFU and the second part defines the UID size and anticollision bits. The value 00000 for the anticollision is defined as RFU.
But according to NXP MIFARE Type Identification Procedure (AN10833) byte 1 of the ATQA can be 0x04. Anyways I can not find MIFARE Classic hex value for the ATQA compatible in the previously mentioned document. Also the document MF1S50YYX_V1 states that the hex value of the ATQA of a Mifare Classic card should be 00 xx.
I am pretty sure that I am reading the ATQA in the correct endianess (I am able to perform a full anticollision procedure) so I can't figure what's going on with the ATQA. Any hint would be very appreciated.
I'm not sure I understand your problem. 04 00 looks like a valid ATQA for MIFARE Classic under the assumption that the octets are ordered in transmission byte order (lower byte first).
The coding of the ATQA according to ISO/IEC 14443-3 is:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
| 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
| RFU | PROPR. CODING | UID SIZE | RFU | BIT FRAME ANTICOLLISION |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
Since bits 8..1 are the LSB (first transmitted octet) and bits 16..9 are the MSB (second transmitted octet), your ATQA would map to:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
| 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
| RFU | PROPR. CODING | UID SIZE | RFU | BIT FRAME ANTICOLLISION |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
| 0x00 | 0x04 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
So your MIFARE Classic card could be either Classic 1K or Mini (or Plus) with a 4-byte (N)UID. Note that you should not rely on the ATQA to detect UID length and chip type though (this should be done through selection and evaluation of the SAK value).

MKV seekhead parsing

I have a requirement, where I need to parse a matroska file. Initial few bytes of file is given as below.
0x1a 0x45 0xdf 0xa3 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x23 0x42 0x86 0x81 0x01
0x42 0xf7 0x81 0x01 0x42 0xf2 0x81 0x04 0x42 0xf3 0x81 0x08 0x42 0x82 0x88 0x6d
0x61 0x74 0x72 0x6f 0x73 0x6b 0x61 0x42 0x87 0x81 0x04 0x42 0x85 0x81 0x02 0x18
0x53 0x80 0x67 0x01 0x00 0x00 0x00 0x00 0x33 0xdb 0x10 0x11 0x4d 0x9b 0x74 0x40
0x42 0xbf 0x84 0x11 0xac 0x83 0x8a 0x4d 0xbb 0x8b 0x53 0xab 0x84 0x15 0x49 0xa9
0x66 0x53 0xac 0x81 0xe5 0x4d 0xbb 0x8c 0x53 0xab 0x84 0x16 0x54 0xae 0x6b 0x53
0xac 0x82 0x01 0x56 0x4d 0xbb 0x8c 0x53 0xab 0x84 0x12 0x54 0xc3 0x67 0x53 0xac
0x82 0x11 0x5c 0x4d 0xbb 0x8d 0x53 0xab 0x84 0x1c 0x53 0xbb 0x6b 0x53 0xac 0x83
0x33 0xd9 0x1c 0xec 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x94 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
I am trying to parse this file. I have parsed first 59 bytes successfully. Now I am at 60th byte. From 6th byte bytes are 0x11 0x4d 0x9b 0x74 (shown in bold), so it means seekhead is starting.
I used mkvinfo to view parsed data. As per mkvinfo as shown below, seekhead starts at 59 which is fine.
Looks the first seek entry starts at 71. Now from 59th to 71st position what is there. This part I am not able to understand.
Can somebody please help me to understand this part.
You should parse the bytes like this† (refer to the Matroska specification for details):
0x11 0x4d 0x9b 0x74 (element ID: SeekHead)
0x40 0x42 (element size: 66)
0xbf (element ID: CRC-32)
0x84 (element size: 4)
0x11 0xac 0x83 0x8a (4-byte CRC-32 value)
0x4d 0xbb (element ID: Seek)
0x8b (element size: 11)
0x53 0xab (element ID: SeekID)
0x84 (element size: 4)
0x15 0x49 0xa9 0x66 (SeekID value; refers to Info element ID)
0x53 0xac (element ID: SeekPosition)
0x81 (element size: 1)
0xe5 (SeekPosition value: 229)
0x4d 0xbb (element ID: Seek)
0x8c (element size: 12)
0x53 0xab (element ID: SeekID)
0x84 (element size: 4)
0x16 0x54 0xae 0x6b (SeekID value; refers to Tracks element ID)
0x53 0xac (element ID: SeekPosition)
0x82 (element size: 2)
0x01 0x56 (SeekPosition value: 342)
0x4d 0xbb (element ID: Seek)
0x8c (element size: 12)
0x53 0xab (element ID: SeekID)
0x84 (element size: 4)
0x12 0x54 0xc3 0x67 (SeekID value; refers to Tags element ID)
0x53 0xac (element ID: SeekPosition)
0x82 (element size: 2)
0x11 0x5c (SeekPosition value: 4444)
0x4d 0xbb (element ID: Seek)
0x8d (element size: 13)
0x53 0xab (element ID: SeekID)
0x84 (element size: 4)
0x1c 0x53 0xbb 0x6b (SeekID value; refers to Cues element ID)
0x53 0xac (element ID: SeekPosition)
0x83 (element size: 3)
0x33 0xd9 0x1c (SeekPosition value: 3397916)
0xec (element ID: Void)
[I stopped parsing here]
A simplified ASCII graphic of the structure of these specific bytes is as follows:
+- SeekHead -------+
| CRC-32 |
| +- Seek--------+ |
| | SeekID | |
| | SeekPosition | |
| +--------------+ |
| +- Seek--------+ |
| | SeekID | |
| | SeekPosition | |
| +--------------+ |
| +- Seek--------+ |
| | SeekID | |
| | SeekPosition | |
| +--------------+ |
| +- Seek--------+ |
| | SeekID | |
| | SeekPosition | |
| +--------------+ |
+------------------+
Void
I've drawn the master elements (elements which contain other elements) as boxes.
To answer your specific question:
Looks the first seek entry starts at 71. Now from 59th to 71st position what is there. This part I am not able to understand.
The SeekHead begins at byte 59. It's size begins 4 bytes later at byte 63. After that, a CRC-32 element begins at byte 65. After that, at byte 71, the first Seek element is found.
†I've just parsed this mentally by hand; hopefully I haven't made any errors or typos.

Meaning of a Common String In Executables?

There appear to be some similar-looking long alphanumeric strings that commonly occur in Mach-O 64 bit executables and ELF 64-bit LSB executables among other symbols that are not alphanumeric:
cat /bin/bash | grep -c "AWAVAUATSH"
has 181 results, and
cat /usr/bin/gzip | grep -c "AWAVAUATSH"
has 9 results.
What are these strings?
Interesting question. Since I didn't know the answer, here are the steps I took to figure it out:
Where in the file does the string occur?
strings -otx /bin/gzip | grep AWAVAUATUSH
35e0 AWAVAUATUSH
69a0 AWAVAUATUSH
7920 AWAVAUATUSH
8900 AWAVAUATUSH
92a0 AWAVAUATUSH
Which section is that in?
readelf -WS /bin/gzip
There are 28 section headers, starting at offset 0x16860:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 0000000000400238 000238 00001c 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 000254 000020 00 A 0 0 4
[ 3] .note.gnu.build-id NOTE 0000000000400274 000274 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 000298 000038 00 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002d0 0002d0 000870 18 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400b40 000b40 000360 00 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000400ea0 000ea0 0000b4 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400f58 000f58 000080 00 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400fd8 000fd8 000090 18 A 5 0 8
[10] .rela.plt RELA 0000000000401068 001068 0007e0 18 A 5 12 8
[11] .init PROGBITS 0000000000401848 001848 00001a 00 AX 0 0 4
[12] .plt PROGBITS 0000000000401870 001870 000550 10 AX 0 0 16
[13] .text PROGBITS 0000000000401dc0 001dc0 00f1ba 00 AX 0 0 16
[14] .fini PROGBITS 0000000000410f7c 010f7c 000009 00 AX 0 0 4
... etc.
From above output, we see that all instances of AWAVAUATUSH are in .text section (which covers [0x1dc0, 0x10f7a) offsets of the file.
Since this is .text, we expect to find executable instructions there. The address we are interested in is 0x401dc0 (.text address) + 0x35e0 (offset of AWAVAUATUSH in the file) - 0x1dc0 (offset of .text in the file) == 0x4035e0.
First, let's check that the above arithmetic is correct:
gdb -q /bin/gzip
(gdb) x/s 0x4035e0
0x4035e0: "AWAVAUATUSH\203\354HdH\213\004%("
Yes, it is. Next, what are the instructions there?
(gdb) x/20i 0x4035e0
0x4035e0: push %r15
0x4035e2: push %r14
0x4035e4: push %r13
0x4035e6: push %r12
0x4035e8: push %rbp
0x4035e9: push %rbx
0x4035ea: sub $0x48,%rsp
0x4035ee: mov %fs:0x28,%rax
0x4035f7: mov %rax,0x38(%rsp)
0x4035fc: xor %eax,%eax
0x4035fe: mov 0x213363(%rip),%rax # 0x616968
0x403605: mov %rdi,(%rsp)
0x403609: mov %rax,0x212cf0(%rip) # 0x616300
0x403610: cmpb $0x7a,(%rax)
0x403613: je 0x403730
0x403619: mov $0x616300,%ebx
0x40361e: mov (%rsp),%rdi
0x403622: callq 0x4019f0 <strlen#plt>
0x403627: cmp $0x20,%eax
0x40362a: mov %rax,0x8(%rsp)
These indeed look like normal executable instructions. What is the opcode of push %r15? This table shows that 0x41, 0x57 is indeed push %r15, and these opcodes just happen to spell AW in ASCII. Similarly, push %r14 is encoded as 0x41, 0x56, which just happens spell AV. Etc.
P.S. My version of gzip is fully stripped, which is why GDB shows no symbols in the above disassembly. If I use a non-stripped version instead, I see:
strings -o -tx gzip | grep AWAVAUATUSH | head -1
6be0 AWAVAUATUSH
readelf -WS gzip | grep text
[13] .text PROGBITS 0000000000401b00 001b00 00d102 00 AX 0 0 16
So the string is still in .text.
gdb -q ./gzip
(gdb) p/a 0x0000000000401b00 + 0x6be0 - 0x001b00
$1 = 0x406be0 <inflate_dynamic>
(gdb) disas/r 0x406be0
Dump of assembler code for function inflate_dynamic:
0x0000000000406be0 <+0>: 41 57 push %r15
0x0000000000406be2 <+2>: 41 56 push %r14
0x0000000000406be4 <+4>: 41 55 push %r13
0x0000000000406be6 <+6>: 41 54 push %r12
0x0000000000406be8 <+8>: 55 push %rbp
0x0000000000406be9 <+9>: 53 push %rbx
0x0000000000406bea <+10>: 48 81 ec 38 05 00 00 sub $0x538,%rsp
...
Now you can clearly see the ASCII 0x4157415641554154... sequence of opcodes.
P.P.S. The original question asks about AWAVAUATSH, which does appear in my Mach-O bash and gzip, but not in Linux ones. Conversely, AWAVAUATUSH does not appear in my Mach-O binaries.
The answer is however the same. The AWAVAUATSH sequence is the same as AWAVAUATUSH, but with push %rbp omitted.
P.P.P.S Here are some other "fun" strings of the same nature:
strings /bin/bash | grep '^A.A.A.' | sort | uniq -c | sort -nr | head
44 AWAVAUATUSH
27 AVAUATUSH
16 AWAVAUA
15 AVAUATUH
14 AWAVAUI
14 AWAVAUATUH
12 AWAVAUATI
8 AWAVAUE1
8 AVAUATI
6 AWAVAUATU

ATMega328p AVRDude RC=-1 with USBTinyISP

I now tried the 8th time to program my ATMega328p with the USBTinyISP from ADAFRUIT. AVRDude still returns this error:
avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch
System wide configuration file is "C:\WinAVR-20100110\bin\avrdude.conf"
Using Port : lpt1
Using Programmer : usbtiny
AVR Part : ATMEGA328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 5 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : USBtiny
Description : USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/
avrdude: programmer operation not supported
avrdude: Using SCK period of 10 usec
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude done. Thank you.
To double check I did:
Use the USBTinyISP with my arduino UNO and connected it to the board, tested with avrdude and could connect successfully. So the connector is fine.
I do not know where to search anymore.

Mifare 1k value block operations

I have a problem with a Mifare Standard 1k card. I made a value block (00000001FFFFFFFE0000000100FF00FF - valid?) on the data block with address 62. The value of the value block is supposed to be 1, and address of the value block is 0.
I've changed the access bits for the data block 2 to be:
C1=1
C2=1
C3=0
The other 2 data blocks have factory access bits. Access bits for the sector trailer are also changed and are:
C1=0
C2=1
C3=1
So, access bits for the corresponding sector (16th sector) are 3B478C69 (valid?).
The problem is that I can't do any of the value block specific functions on that block (increment, decrement, etc), I always get 6A81 as response -> "Card is blocked or command not supported".
The APDU I'm using is FFF5C13E0400000001.
OMNIKEY readers have extensions to the PC/SC API for contactless memory cards. The commands defined by these extensions for increment and decrement of MIFARE Classic value blocks are:
Increment:
+------+------+------+------+------+-------------+
| CLA | INS | P1 | P2 | Lc | DATA |
+------+------+------+------+------+-------------+
| 0xFF | 0xD4 | BLOCK# | 0x04 | XX 00 00 00 |
+------+------+------+------+------+-------------+
or (depending on the firmware version???) the same command with a 1-byte data field:
+------+------+------+------+------+----+
| 0xFF | 0xD4 | BLOCK# | 0x01 | XX |
+------+------+------+------+------+----+
Decrement:
+------+------+------+------+------+-------------+
| CLA | INS | P1 | P2 | Lc | DATA |
+------+------+------+------+------+-------------+
| 0xFF | 0xD8 | BLOCK# | 0x04 | XX 00 00 00 |
+------+------+------+------+------+-------------+
or (depending on the firmware version???) the same command with a 1-byte data field:
+------+------+------+------+------+----+
| 0xFF | 0xD8 | BLOCK# | 0x01 | XX |
+------+------+------+------+------+----+
BLOCK#:
P1 is the MSB of the block number (always zero) and P2 is the LSB of the block number.
XX:
The increment/decrement value.
The commands are documented in OMNIKEY Contactless Smart Card Readers Developer Guide.
It seems as if both commands implicitly issue a transfer command to commit the operation. A restore command is not documented for the PC/SC extensions, however, the restore command is available through the OMNIKEY synchronous API.

Resources