(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a
ハードウェアハッキングして NFC コントローラの命令を解析する
https://qiita.com/nanbuwks/items/8baa0408e08812258c95
では elechouse のArduinoライブラリの通信内容を解析してみました。
しかしながら、初期化ルーチンはこれだけでは不足しているみたい。改めて初期化ルーチンを調べてみました。今まであれこれ試して調子が良かった、 nfclib の pn53x-tamashell の通信内容を調べてみました。
環境
(ターゲット)
- PN532 NFC Module SPI I2C Reader/Writer Breakout Board
- 電解コンデンサ追加加工済
- cf., 「NFC モジュールの動作安定性を改善する」
- https://qiita.com/nanbuwks/items/a9217ba2e8f206b899b1
- Raspberry Pi Model B+ V1.2
- Raspberry Pi OS Lite armhf-2020-12-04
- libnfc 1.8.0
- cf., 「Raspberry Pi で libnfc + PN532 NFC RFID module」
- https://qiita.com/nanbuwks/items/0c73add503b354774035
(シリアルハードウエアモニター)
- WEMOS LOLIN32
- ( ≒ ESP32 DevKitC )
- Arduino 1.8.10 Linux 版
- portable 化済
- esp32 by Espressif Systems Version 1.0.3
- Ubuntu Linux 20.04 AMD64
ESP32 でシリアルのハードウェアモニター
「ハードウェアハッキングして NFC コントローラの命令を解析する」
https://qiita.com/nanbuwks/items/8baa0408e08812258c95
のものより改良して、通信した時刻を表示するようにしました。
以下がESP32 のスケッチです。
char dumpbuff[50];
char countbuff[50];
//HardwareSerial Serial1(2);
void setup() {
Serial.begin(115200);
Serial2.begin(115200);
}
void loop() {
unsigned long time,timesec,timemicrosec;
char timestr[50];
int counter=0;
int oldcounter=0;
for (int counter=0;counter<65536;counter++){
dumpbuff[0]=0;
time=micros();
for (int address=0;address<16;address++){
if (Serial2.available()) {
int inByte = Serial2.read();
sprintf(dumpbuff, "%s %02X",dumpbuff,inByte);
} else {
sprintf(dumpbuff, "%s --",dumpbuff);
}
delayMicroseconds(20);
}
if ( 0 != strcmp(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --",dumpbuff )){ // 空ではなかった場合
if ( oldcounter != counter -1 )
{
Serial.println("...");
}
oldcounter=counter;
timesec=time/1000000;
timemicrosec=time % 1000000;
sprintf(timestr, "%d.%06d ", timesec,timemicrosec);
Serial.print(timestr);
sprintf(countbuff, "%07X0: ",counter);
Serial.print(countbuff);
Serial.println(dumpbuff);
}
}
}
配線は、先のリンクと同様に行いました。
TAMASHELL のログ
RaspberryPi から TAMASHELL を使ったときのログを取ってみました。
$ ./pn53x-tamashell
NFC reader: Itead_PN532 opened
として起動した時と、
> quit
quit
Bye!
として終了したときのログを取ってみました。
起動した時のログ
...
161.637661 000CAC80: -- -- -- -- 55 55 00 00 00 00 00 00 00 00 00 00
161.638298 000CAC90: 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 -- --
...
161.641535 000CACE0: -- -- -- -- -- -- -- 00 00 FF 09 F7 D4 00 00 6C
161.646429 000CACF0: 69 62 6E 66 63 BE 00 00 00 FF 02 FE D4 02 2A 00
161.652592 000CAD00: 00 00 FF 03 FD D4 12 14 06 00 -- -- -- -- -- --
161.658755 000CAD10: 00 00 FF 0C F4 D4 06 63 02 63 03 63 0D 63 38 63
161.664918 000CAD20: 3D B0 00 00 00 FF 08 F8 D4 08 63 02 80 63 03 80
161.671081 000CAD30: 59 00 00 00 FF 04 FC D4 32 01 00 F9 00 -- -- --
161.677244 000CAD40: 00 00 FF 04 FC D4 32 01 01 F8 00 00 00 FF 06 FA
161.683407 000CAD50: D4 32 05 FF FF FF F8 00 -- -- -- -- -- -- -- --
終了時のログ
...
171.410499 00023ED0: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 00
171.411063 00023EE0: 00 FF 0E F2 D4 06 63 02 63 03 63 05 63 38 63 3C
171.412604 00023EF0: 63 3D 19 00 -- -- -- -- -- -- -- -- -- -- -- --
171.418767 00023F00: 00 00 FF 08 F8 D4 08 63 05 40 63 3C 10 CD 00 --
171.424930 00023F10: 00 00 FF 03 FD D4 52 00 DA 00 00 00 FF 04 FC D4
171.431093 00023F20: 32 01 00 F9 00 -- -- -- -- -- -- -- -- -- -- --
171.437256 00023F30: 00 00 FF 03 FD D4 16 F0 26 00 -- -- -- -- -- --
これらを、読み解いていきます。
ログの読み方
...
161.637661 000CAC80: -- -- -- -- 55 55 00 00 00 00 00 00 00 00 00 00
161.638298 000CAC90: 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 -- --
これの、161.637661 は ESP32 の分析プログラムを起動してからの 秒数:マイクロ秒 で表しています。
プログラムは20マイクロ秒ごとにポーリングし、無ければ NULL とし、-- で表現 、あれば16進数で表示しています。
000CAC80:は NULL も1バイトとした、分析ブログラムを起動してからのバイト数カウントです。
初期化ルーチン
HSU wake up condition
55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SAMConfiguration
00 00 FF 03 FD D4 14 01 17 00
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
03 | パケット長 |
FD | パケット長のチェックサム |
D4 14 01 | パケット内容 |
17 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
14 | 命令:SAMConfiguration |
01 | 命令:SAMを利用しないノーマルモード |
Diagnose
00 00 FF 09 F7 D4 00 00 6C 69 62 6E 66 63 BE 00
00 | プリアンブル |
00 FF | スタートコード |
09 | パケット長 |
F7 | パケット長のチェックサム |
D4 00 00 6C 69 62 6E 66 63 | パケット内容 |
BE | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
00 | 命令:NumTst = 0x00: Communication Line Test |
00 6C 69 62 6E 66 63 | 通信テスト送信データ |
GetFirmwareVersion
00 00 FF 02 FE D4 02 2A 00
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
02 | パケット長 |
FE | パケット長のチェックサム |
D4 02 | パケット内容 |
2A | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
02 | 命令:GetFirmwareVersion |
SetParameters
00 00 FF 03 FD D4 12 14 06 00
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
03 | パケット長 |
FD | パケット長のチェックサム |
D4 12 14 | パケット内容 |
06 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
12 | 命令:SetParameters |
14 | 命Flags=0x14:Automatic generation of the RATS in case of |
ISO/IEC14443-4 PCD mode , Automatic generation of the ATR_RES in | |
case of target configuration. |
ReadRegister
00 00 FF 0C F4 D4 06 63 02 63 03 63 0D 63 38 63 3D B0 00
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
0C | パケット長 |
F4 | パケット長のチェックサム |
D4 06 63 02 63 03 63 0D 63 38 63 3D | パケット内容 |
B0 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
06 | 命令:ReadRegister |
63 02 | Defines the transmission data rate and framing during transmission. |
63 03 | Defines the reception data rate and framing during receiving. |
63 0D | Allows manual fine tuning of the internal receiver. |
63 38 | Contain status flags of the receiver, transmitter and Data Mode Detector. |
63 3D | Adjustments for bit oriented frames. |
WriteRegister
00 00 FF 08 F8 D4 08 63 02 80 63 03 80 59 00
00 | プリアンブル |
00 FF | スタートコード |
08 | パケット長 |
F8 | パケット長のチェックサム |
D4 08 63 02 80 63 03 80 | パケット内容 |
59 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
08 | 命令:WriteRegister |
63 02 | Defines the transmission data rate and framing during transmission. |
80 | TxSpeed=106kbit/s , the modulation for transmitting data is inverted. , data transmission is ISO/IEC 14443A/MIFARE and Passive Communication |
mode 106 kbit/s | |
63 03 | Defines the reception data rate and framing during receiving. |
80 | RxSpeed=106kbit/s ,a not valid received data stream (less than 4 bits received) will be ignored. The receiver will remain active. , data reception is ISO/IEC 14443A/MIFARE and Passive Communication mode 106 kbit/s |
RFConfiguration
00 00 FF 04 FC D4 32 01 00 F9 00
00 | プリアンブル |
00 FF | スタートコード |
04 | パケット長 |
FC | パケット長のチェックサム |
D4 32 01 00 | パケット内容 |
F9 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
32 | 命令:RFConfiguration |
01 | CfgItem=0x01:RF field |
00 | AutoRFCA is off,RF if off |
RFConfiguration
00 00 FF 04 FC D4 32 01 01 F8 00
00 | プリアンブル |
00 FF | スタートコード |
04 | パケット長 |
FC | パケット長のチェックサム |
D4 32 01 00 | パケット内容 |
F8 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
32 | 命令:RFConfiguration |
01 | CfgItem=0x01:RF field |
01 | AutoRFCA is off,RF if on |
これは先の命令と合わせ、RFをOFF→ONにしているだけですが、ログを見ると2つの命令発行の間に数ミリ秒~数十ミリ秒の間が空いていることがわかります。
RFConfiguration
00 00 FF 06 FA D4 32 05 FF FF FF F8 00
00 | プリアンブル |
00 FF | スタートコード |
06 | パケット長 |
FA | パケット長のチェックサム |
D4 32 05 FF FF FF | パケット内容 |
F8 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
32 | 命令:RFConfiguration |
05 | CfgItem = 0x05:MaxRetries |
FF | MxRtyATR=0xFF: try eternally |
FF | MxRtyPSL=0xFF: try eternally |
FF | MxRtyPassiveActivation=0xFF:infinitely |
終了処理
ReadRegister
00 00 FF 0E F2 D4 06 63 02 63 03 63 05 63 38 63 3C 63 3D 19 00
これは以下のような構成になっています。
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
0E | パケット長 |
F2 | パケット長のチェックサム |
D4 06 63 02 63 03 63 05 63 38 63 3C 63 3D | パケット内容 |
19 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
06 | 命令:ReadRegister |
63 02 | Defines the transmission data rate and framing during transmission. |
63 03 | Defines the reception data rate and framing during receiving. |
63 05 | Controls the setting of the antenna driver. |
63 38 | Contain status flags of the receiver, transmitter and Data Mode Detector. |
63 3C | Contains miscellaneous control bits. |
63 3D | Adjustments for bit oriented frames. |
WriteRegister
00 00 FF 08 F8 D4 08 63 05 40 63 3C 10 CD 00
00 | プリアンブル |
00 FF | スタートコード |
08 | パケット長 |
F8 | パケット長のチェックサム |
D4 08 63 05 40 63 3C 10 | パケット内容 |
CD | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
08 | 命令:WriteRegister |
63 05 | Controls the settings of the antenna driver |
40 | Force100ASK forces a 100% ASK modulation independent of |
the setting in CIU_ModGsP register. | |
63 3C | Contains miscellaneous control bits. |
10 | the PN532 acts as Initiator or Reader/Writer, otherwise it acts as Target. or a Card. |
InRelease
00 00 FF 03 FD D4 52 00 DA 00
00 | プリアンブル |
00 FF | スタートコード |
03 | パケット長 |
FD | パケット長のチェックサム |
D4 52 00 | パケット内容 |
DA | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
52 | 命令:InRelease |
00 | すべてのターゲット |
RFConfiguration
00 00 FF 04 FC D4 32 01 00 F9 00
00 | プリアンブル |
00 FF | スタートコード |
04 | パケット長 |
FC | パケット長のチェックサム |
D4 32 01 00 | パケット内容 |
F9 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
32 | 命令:RFConfiguration |
01 | CfgItem = 0x01:RF field |
00 | AutoRFCA is off,RF if off |
PowerDown
00 00 FF 03 FD D4 16 F0 26 00
00 | プリアンブル |
00 FF | スタートコード |
03 | パケット長 |
FD | パケット長のチェックサム |
D4 16 F0 | パケット内容 |
26 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
16 | 命令:PowerDown |
F0 | WakeUpEnable parameter=0xF0:I2C,GPIO,SPI,HSU selected |