## Kiwi PN532 SPI library for Arduino This is a minimal and efficient SPI library using IRQ instead of status polling, compatible with: - Arduino Uno R3, Arduino Leonardo - @ 4 MHz - Arduino Uno R4 Minima (maybe WiFi too?) - @ 3 MHz (see `kpn532.h` to know why this 1 MHz does not make a lots of differences) ### GitHub repository https://github.com/BdF-LabSec/kpn532 ### Updates - IRQ are now on pin 3 & 2 (only ones available on R3 for real IRQ) - No more minimal/verbose pin - use specific firmware (outputs slow down the relay) - `kpn532` is now a library, `relay` is now available as an example (as `st25tb` to read one card) ## Arduino Uno R4 vs. Elechouse PN532 boards _Or why to start with a Uno R3..._ ### Bits and Bytes order... First versions of Uno R4 SPI Class had a bug when dealing with `LSB` settings: bits were reversed, but bytes too... creating problems when transfering blocks. ![LSB bytes order problem](lsb_problem.png) It was fixed by @RudolphRiedel (https://github.com/arduino/ArduinoCore-renesas/pull/246). Thanks to him, we now have correct & efficient SPI transfer. ### Logical level Arduino R3 & R4 boards are both using 5V logical level (`1` is ~5V), but Elechouse PN532 boards are using : "On-board level shifter, Standard 5V TTL for I2C and UART, 3.3V TTL SPI" We were lucky with Arduino R3: - (ATmega328P) R3 `1`: 0.6xVCC: 3V, tolerant to 2.4V (measured) - (Renesas RA4M1) R4 `1`: 0.8xVCC: 4V, tolerant to 3.1V (measured) Unfortunately, the Elechouse PN532 SPI is ~3V (sometimes even ~2.9V). It makes some `1` (from PN532 point of view) to be read as `0` (on the Ardunion Uno R4). It's particularly annoying with `IRQ` signals. - PN532 is nice with our 5V output signals instead of 3V (`SCK`, `MOSI`, `CS`) - _but it's not ideal_, - Arduino Uno R4 is less nice, and have problem with `MISO` and `IRQ`. It can be _solved_ with a level shifter: search on Amazon for `TXS0108E Logic Level Converter` - or build a [kpn532 board](#kpn532-board) (rely on `TXS0108EPWR`) ## Programming Arduino IDE is enough to handle build and flash to devices, but you can also flash binaries with: - `avrdude` - with HEX file - for Arduino Uno R3 (or another programmer) ``` > avrdude -p atmega328p -c arduino -P COM8 -b 115200 -D -U flash:w:kpn532_foo.hex:i ``` - `dfu-util` - with BIN file - for Arduino Uno R4 (or another programmer) ``` > dfu-util --list dfu-util 0.11 Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. Copyright 2010-2021 Tormod Volden and Stefan Schmidt This program is Free Software and has ABSOLUTELY NO WARRANTY Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ Found DFU: [2341:0369] ver=0100, devnum=50, cfg=1, intf=0, path="1-7.2.1.2", alt=1, name="@DataFlash /0x08000000/8*1Kg", serial="370B0B185931393864FA33324B572E3F" Found DFU: [2341:0369] ver=0100, devnum=50, cfg=1, intf=0, path="1-7.2.1.2", alt=0, name="@CodeFlash /0x00000000/8*2Ka,120*2Kg", serial="370B0B185931393864FA33324B572E3F" ``` Use the `@CodeFlash` one (here, `alt=0`) ``` > dfu-util --serial 370B0B185931393864FA33324B572E3F --alt 0 --reset --download kpn532_foo.ino.bin dfu-util 0.11 Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. Copyright 2010-2021 Tormod Volden and Stefan Schmidt This program is Free Software and has ABSOLUTELY NO WARRANTY Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ Warning: Invalid DFU suffix signature A valid DFU suffix will be required in a future dfu-util release Opening DFU capable USB device... Device ID 2341:0069 Run-Time device DFU version 0101 Claiming USB DFU (Run-Time) Interface... Setting Alternate Interface zero... Determining device status... DFU state(0) = appIDLE, status(0) = No error condition is present Device really in Run-Time Mode, send DFU detach request... Device will detach and reattach... Opening DFU USB Device... Claiming USB DFU Interface... Setting Alternate Interface #0 ... Determining device status... DFU state(2) = dfuIDLE, status(0) = No error condition is present DFU mode device DFU version 0101 Device returned transfer size 64 Copying data from PC to DFU device Download [=========================] 100% 61936 bytes Download done. DFU state(7) = dfuMANIFEST, status(0) = No error condition is present DFU state(2) = dfuIDLE, status(0) = No error condition is present Done! Resetting USB to switch back to Run-Time mode ``` ## kpn532 board After many tests, many wires, many problems, many probes, etc... I created a minimal shield to experiment `PN532` relaying with - not expensive - Elechouse PN532 boards. But it can also be used to help only one PN532 board with the level shifter. ![Picture kpn532 board PCB 3D representation](kpn532_board_3d.png) Schematic is very simple, you can find the project at: https://oshwlab.com/gentilkiwi/arduino_uno_relay_board Arduino Uno Relay board is designed for `Uno` boards, as it is working with 5V logical level and SPI pins (SCK/MOSI/MISO) are available on standard connector (not like `Leonardo` boards). ## Pictures ### New version with `kpn532 board` ![Picture of Arduino UNO R4 minima and two Elechouse NFC module v3, on a kpn532 board with level shifter](kpn532_board_r4.jpg) ### Previous version with wires and previous pinning ![Picture of Arduino UNO R3 and two Elechouse NFC module v3, wired to SPI bus & powered](kpn532_direct.jpg) ## Examples ### kpn532_kirelay #### Hardware list - 1 x Arduino Uno R3 - 2 x Elechouse NFC Module V3 (or V4) - 14 x Dupont wires - or a [kpn532 relay board](#kpn532-board) :) - 7 x F/M - 7 x F/F #### Wiring diagram ``` ARDUINO READER EMULATOR +-----+ +----[PWR]-------------------| USB |--+ .. ------------------------- .. ------------------------- |                            +-----+  | .. -------------------------\\ .. -------------------------\\ |        GND[a][ ]RST2            | ELECHOUSE NFC MODULE V3 || ELECHOUSE NFC MODULE V3 || |      MOSI2[ ][ ]SCK2  A5/SCL[ ] | [ ] [ ] [ ] [ ] __ || [ ] [ ] [ ] [ ] __ || |         5V[b][ ]MISO2  A4/SDA[ ] | SCL SDA VCC GND / \ || SCL SDA VCC GND / \ || |                             AREF[ ] | \__/ || \__/ || |                              GND[ ] | 1|#_|ON (SPI) || 1|#_|ON (SPI) || | [ ]N/C                    SCK/13[c] | 2|_#|KE SCK[c] || 2|_#|KE SCK[i] || | [ ]IOREF                 MISO/12[d] | MISO[d] || MISO[j] || | [ ]RST                   MOSI/11[e]~| ||||| MOSI[e] || ||||| MOSI[l] || | [ ]3V3    +---+               10[f]~| +-----+ SS[f] || +-----+ SS[n] || | [ ]5v    -| A |-               9[n]~| -|PN532|- VCC[b] || -|PN532|- VCC[m] || | [ ]GND   -| R |-               8[ ] | +-----+ GND[a] || +-----+ GND[k] || | [ ]GND   -| D |-                    | ||||| IRQ[g] || ||||| IRQ[o] || | [ ]Vin   -| U |-               7[ ] | RSTO[ ] || RSTO[ ] || |          -| I |-               6[ ]~| |HSU| 0 | 0 || |HSU| 0 | 0 || | [ ]A0    -| N |-               5[ ]~| |I2C| 1 | 0 .. |I2C| 1 | 0 .. | [ ]A1    -| O |-               4[ ] | |SPI| 0 | 1 .. |SPI| 0 | 1 .. | [ ]A2     +---+           INT1/3[g]~| | [ ]A3                     INT0/2[o] | SHARED a <-> k (GND) READER ONLY f (SS) | [p]A4/SDA  RST SCK MISO     TX>1[ ] | b <-> m (5V) g (IRQ) | [q]A5/SCL  [ ] [i] [j]      RX<0[ ] | c <-> i (SCK) EMULATOR ONLY n (SS) |            [k] [l] [m]              | d <-> j (MISO) o (IRQ) |  UNO R3    GND MOSI 5V  ____________/ e <-> l (MOSI) \_______________________/ ``` #### Performance Measured _waiting_ time for `GetVersion` instruction (`0x60`) is ~20,3ms. Two `WTX` frames are present bewtween. ![Measured waiting time for GetVersion instruction on relayed configuration, WTX frames before answer](kpn532_proxified_getversion.png) A normal _waiting_ time is around ~383µs for this instruction ![Measured waiting time for GetVersion instruction on direct configuration](kpn532_direct_getversion.png) The proxified penalty is around 20ms, more or less depending on the payload size. You can check timings with `SDR nfc-laboratory v2.0` #### Behavior ##### Presented UID Presented UID can be different from the original. - Original UID: `0495910A5D6D80` - Presented UID: `0895910A` - `08` is forced by `PN532` design ; - Only 4 bytes in total, 3 bytes available. #### Seen as `Felica` Sometimes the presented card can be seen as `Felica`. Move the original card to a better position on the antenna, then try again (with a `reset`). #### Traces With a NXP TagInfo scan ##### Minimal mode ``` .#####. kirelay 0.2 (Arduino with kpn532 - single board) .## ^ ##.__ _ "A La Vie, A L'Amour" - (oe.eo) ## / \ / ('>- ## \ / | K | /*** Benjamin DELPY `gentilkiwi` '## v #\____/ [email protected] '#####' L\_ [email protected] ***/ | Relay verbosity: minimal | Relay mode : ISO/DEP | PN532 #0 - Reader init... | PN532 version 1.6.7 | CIU Version 0x80 | PN532 #1 - Emulator init... | PN532 version 1.6.7 | CIU Version 0x80 | Initialization OK! ~ Waiting for target... | Detected target | SENS_RES: 0344 | SEL_RES : 20 | UID : 0495910A5D6D80 ~ Waiting for reader on emulator... | Reader detected! | Target released ``` ##### Verbose - `<` from reader - `>` to reader ``` .#####. kirelay 0.2 (Arduino with kpn532 - single board) .## ^ ##.__ _ "A La Vie, A L'Amour" - (oe.eo) ## / \ / ('>- ## \ / | K | /*** Benjamin DELPY `gentilkiwi` '## v #\____/ [email protected] '#####' L\_ [email protected] ***/ | Relay verbosity: full | Relay mode : ISO/DEP | PN532 #0 - Reader init... | PN532 version 1.6.7 | CIU Version 0x80 | PN532 #1 - Emulator init... | PN532 version 1.6.7 | CIU Version 0x80 | Initialization OK! ~ Waiting for target... | Detected target | SENS_RES: 0344 | SEL_RES : 20 | UID : 0495910A5D6D80 ~ Waiting for reader on emulator... | Reader detected! < 00A4040007D276000085010100 > 6A82 < 00A4040007D276000085010000 > 9000 < 9060000000 > 04010133001A0591AF < 90AF000000 > 04010103001A0591AF < 90AF000000 > 0495910A5D6D80995367303020209100 < 00A4040007D276000085010100 > 6A82 < 00A4040007D2760000850100 > 9000 < 00A4000002E103 > 6A82 | Target released ``` ##### TagInfo side ``` ** TagInfo scan (version 4.25.5) 2022-12-22 23:43:24 ** Report Type: -- IC INFO ------------------------------ # IC manufacturer: NXP Semiconductors # IC type: MIFARE DESFire EV3 (MF3D83) -- NDEF ------------------------------ # No NDEF data storage populated: -- EXTRA ------------------------------ # Memory information: Size: 8 kB Available: 8.0 kB (8192 bytes) # IC information: Capacitance: 17 pF # Version information: Vendor ID: NXP (0x04) Hardware info: * Type/subtype: 0x01/0x01 * Version: 3.0 * Storage size: 8192 bytes (0x1A) * Protocol: ISO/IEC 14443-4 (0x05) Software info: * Type/subtype: 0x01/0x01 * Version: 3.0 * Storage size: 8192 bytes (0x1A) * Protocol: ISO/IEC 14443-4 (0x05) Production date: week 20, 2020 (0x2020) # Authentication information: Default PICC master key # Originality Check (asymmetric): Signature could not be verified with NXP public key # Originality Check (symmetric): Originality Check not successful # TagInfo Version: Version :4.25.5 # Device Info: Device Model :samsung ( SM-T636B ) Android OS Version :12 -- FULL SCAN ------------------------------ # Technologies supported: ISO/IEC 7816-4 compatible Native DESFire APDU framing ISO/IEC 14443-4 (Type A) compatible ISO/IEC 14443-3 (Type A) compatible ISO/IEC 14443-2 (Type A) compatible # Android technology information: Tag description: * TAG: Tech [android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NdefFormatable] * Maximum transceive length: 65279 bytes * Default maximum transceive time-out: 618 ms * Extended length APDUs supported * Maximum transceive length: 253 bytes * Default maximum transceive time-out: 618 ms MIFARE Classic support present in Android # Detailed protocol information: ID: 08:95:91:0A * Random ID ATQA: 0x4403 SAK: 0x20 ATS: 0x067533920380 * Max. accepted frame size: 64 bytes (FSCI: 5) * Supported receive rates: - 106, 212, 424 kbit/s (DR: 1, 2, 4) * Supported send rates: - 106, 212, 424 kbit/s (DS: 1, 2, 4) * Different send and receive rates supported * SFGT: 1.208 ms (SFGI: 2) * FWT: 154.7 ms (FWI: 9) * NAD supported * CID supported * Historical bytes: 0x80 |.| # Memory content: Application ID 0x000000 (PICC) * Default master key * Key configuration: (0x0F01) - 1 (3)DES key - Master key changeable - Master key required for: ~ directory list access: no ~ create/delete files: no - Configuration changeable -------------------------------------- ``` ###### Originality checks ``` # Originality Check (asymmetric): Signature could not be verified with NXP public key # Originality Check (symmetric): Originality Check not successful ``` Checks are not successful: signature verification and originality check (with symmetric keys from NXP) are UID dependant, and are using the presented one (not from `GetVersion` answer). As it's altered by PN532 emulation, checks fail. Note: new versions of `NXP TagInfo` avoid to make originaly checks when detecting random/emulated UID. ### kpn532_st25tb ``` .#####. st25tb 0.1 (Arduino with kpn532) .## ^ ##.__ _ "A La Vie, A L'Amour" - (oe.eo) ## / \ / ('>- ## \ / | K | /*** Benjamin DELPY `gentilkiwi` '## v #\____/ [email protected] '#####' L\_ [email protected] ***/ | Verbosity: minimal | PN532 #0 - Init for ST25TB... | PN532 version 1.6.7 | CIU Version 0x80 | Initialization OK! | Initiate: ... ChipId is 0xFB | Select : ... | Get_Uid : ... UID is 7964FF86763302D0 | Block 0x00: 31000000 | Block 0x01: 24570025 | Block 0x02: B3A60004 | Block 0x03: 00204031 | Block 0x04: 00000000 | Block 0x05: 00000031 | Block 0x06: FBFFFFFF | Block 0x07: 00000000 | Block 0x08: 00000000 | Block 0x09: 00000000 | Block 0x0A: B8230000 | Block 0x0B: 09889EFC | Block 0x0C: 1C82A302 | Block 0x0D: E805D762 | Block 0x0E: C39F0080 | Block 0x0F: F22C9C6B | Block 0xFF: FFFFFFFF | Completion: ... END ``` ## Licence CC BY 4.0 licence - https://creativecommons.org/licenses/by/4.0/ ## Author Benjamin DELPY `gentilkiwi`, you can contact me on Twitter ( @gentilkiwi ) or by mail ( benjamin.delpy [at ] banque-france.fr ) This is a POC / experimental development, please respect its philosophy and don't use it for bad things! ## References ### Arduino UNO - R3: https://docs.arduino.cc/hardware/uno-rev3 - R4 minima: https://docs.arduino.cc/hardware/uno-r4-minima #### Wiring diagram adapted from - http://busyducks.com/ascii-art-arduinos ### Elechouse NFC Module - https://www.elechouse.com/product/pn532-nfc-rfid-module-v4/ (same as V3) - https://www.elechouse.com/elechouse/images/product/PN532_module_V3/PN532_%20Manual_V3.pdf - https://www.elechouse.com/elechouse/images/product/PN532_module_V3/PN532_shematic_drowing.pdf ### NXP PN532 - https://www.nxp.com/products/rfid-nfc/nfc-hf/nfc-readers/nfc-integrated-solution:PN5321A3HN - https://www.nxp.com/docs/en/nxp/data-sheets/PN532_C1.pdf - https://www.nxp.com/docs/en/user-guide/141520.pdf ### AVRDUDE - AVR Downloader Uploader - https://github.com/avrdudes/avrdude ### dfu-util - https://sourceforge.net/projects/dfu-util/ ### SDR nfc-laboratory v2.0 - https://github.com/josevcm/nfc-laboratory