出荷時にはNDEF部分(FileNo 2)の設定変更には Key0 の Fullモードじゃないとアクセスできないようになっています。というわけで前回面倒な認証作業を実施しました。Fullモードの場合、APDUのデータの部分が暗号化された形で通信を行います。ざっくり言うと CommandHeader + 設定値の暗号化 + チェックサム的な という形式です。
CommandHeader は 02 のようです。コマンドの詳細仕様を見ると先頭に設定を変更する FileNo を記載すると書いてあるので、恐らく FileNo の 2 のことなんだと思いますがよくわかりません。試せばいいんでしょうけど変な風になる恐ろしさがあるのでタグも10枚しかないしそんなにお手軽にできるシチュエーションでもないのですいません。
設定値は FileOption、AccessRights、SDMOptions、SDMAccessRights、UIDOffset、SDMReadCtrOffset、PICCDataOffset、SDMMACInputOffset、SDMENCOffset、SDMENCLength、SDMMACOffset、SDMReadCtrLimit の順に値を並べます。全部説明してると
FileOption(1バイト) は SDM をやるかやらないかと、通信モードを設定します。SDMやる場合は上から2ビット目を1にします。下位2ビットが通信モードです(Plain = 00、MAC = 01、Full = 11)。ということでここは 40h になります。
AccessRights(2バイト)はアクセス権の設定になります。アクセス権は Read、Write、ReadWrite、Change の4つあって、それぞれ 4ビットの値を設定します。0~4を指定すると、そのキー番号での認証を経てアクセス可能になります。 Eh を指定するとフリーアクセス可能です。Changeというのが Write と何が違うねんという感じですがこれは設定の変更の権限になります。AN12196 では Read:Eh、Write:0h、ReadWrite:0h、Change:0h を指定していますが、これだと Read はフリーなんですが Write が認証必要になるので NDEF部分の書き換えが Plainモードでできなくなってしまいます。のでテストするときはやっぱり書き換えたくなったりするのでここは E0EEh にした方がいいと思います。
SDMOptions(1バイト)はSDMの設定になります。先頭1ビット目から、UIDミラーをするかしないか、カウンターミラーをするかしないか、カウンターリミットの機能を使うか使わないか、SDMENCFileDataを使うか使わないか、下位4ビットは 0001 になります。AN12196 では C1h になってますので、UIDミラーとカウンターミラーをONにしています。(SDMENCFileData:1 になってますが間違いです)
SDMAccessRights(2バイト)はSDM関連のアクセス権の設定になります。4ビットずつで F 固定、SDMCtrRet、SDMMetaRead、SDMFileRead の設定です。0~4を指定するとそのキー番号で暗号化されます。この中でSDMMetaReadがUIDとカウンタの暗号化に関わっていて、2を指定していますのでUID+カウンタが Key2 の値で暗号化されることになります。
後は PICCDataOffset(3バイト)、SDMMACInputOffset(3バイト)、SDMMACOffset(3バイト)の順で設定します。PICCDataOffsetがUID+カウンタを暗号化した値をNDEFのURLのどこに挿入するのかを指定します。
設定値は以上になります。ここから Fullモードでアクセスするために電文を組み立てます。
まず暗号化に使用する IV を作ります。IV は A55A + 認証時に取得したTI + コマンドカウンタ + 0000000000000000 を、認証時に作成した Encryption Session Key で暗号化します。コマンドカウンタはコマンドの番号というか順番というかコマンドを発行するたびに+1する値です。
IV = E(Encryption Session Key:1309C877509E5A215007FF0ED19CA564, A55A + 9D00C4DF + 0100 + 0000000000000000 )
= 3E27082AB2ACC1EF55C57547934E9962
次にこの IV を使って、設定値を暗号化します。
E(Encryption Session Key, IV, 4000E0C1F121200000430000430000 + 80(padding))
= 61B6D97903566E84C3AE5274467E89EA
最後にチェックサム的なところを計算します。
Cmd(5F) + CmdCounter(0100) + TI(9D00C4DF) + CmdHeader(02) +
E(KSesAuthENC, CmdData)
=5F01009D00C4DF0261B6D97903566E84C3AE5274467E89EA
これの AES-CMAC を計算します。
CMAC = 7BD75F991CB7A2C18DA09EEF047A8D04
さらにこれの偶数バイト目だけを集めたものがチェックサム的な値になります。
MACt = D799B7C1A0EF7A04
ここまできてようやく APDU が完成します。
CLA | 90 |
INS | 5F |
P1 | 00 |
P2 | 00 |
Lc | 19 |
Data | 02 61B6D97903566E84C3AE5274467E89EA D799B7C1A0EF7A04 |
Le | 00 |
あー、長かったー。