Artix-7 にて、ビットストリーム(ロジックデータ)を暗号化する例を紹介する。
1. ビットストリーム暗号化の概要
近年、近隣諸国によるコピー商品が横行し、回路のコピープロテクトは欠かせない。
多くの組み込み系CPUやCPLDは、データが同じパッケージ内に記録されており、読み出し禁止などの設定を行えば、
比較的容易にコピープロテクトを掛けることができる。
これに対し、FPGAはロジックデータをパッケージ外のコンフィグレーション用メモリに記録するため、コンフィグレーション用メモリのデータをコピーされてしまうと
コピー商品を作られてしまう可能性がある。
これを防ぐために、コンフィグレーション用メモリに記録されるビットストリームデータ(ロジックデータ)を暗号化することが望ましい。
暗号化の手順は、同じAMD(XILINX)のデバイスでも、型番によって方法が異なる。
ここでは Artix-7(XC7A35TCPG236-1) におけるビットストリーム暗号化手順を紹介する。
なお、暗号キーなどを記録する「eFUSE」 は再書き込みができない (正確には、'1' を書いたビットは'0'に戻せない) ため、
間違って書き込むとやり直しが利かないので注意。
2. 暗号化の基本原理
概要としては、
・コンフィグレーション用メモリに記録されるビットストリーム(ロジックデータ)を暗号化しておく
・複合用の暗号キーは、FPGAの専用メモリー (eFUSE、BBRメモリ) に書き込み、読み出し禁止設定しておく
・FPGA起動時は、暗号化されたビットストリームを暗号キーで複合してからロジックに書き込む
となる。
暗号化されたビットストリームは暗号キーがないと複合できないため、コンフィグレーション用メモリをコピーされても
暗号キーを持たないFPGAでは動作しない。暗号キーを盗まれない限りコピー製品は作れない。
暗号キーを記録する専用メモリーは、Artix-7 の場合
・BBRAM
・eFUSE
の2種類がある。(注意:デバイスによって異なる)
・BBRAM
揮発性メモリで、バックアップ用電源(VCCBAT)を用いることにより、書き込まれた暗号キーを保持する。
バックアップ用電源が切れれば暗号キーも消えてしまうが、消去されることでやり直しが利く。
暗号化の実験を行うには便利。
ただし量産品では、バックアップ用電源などのコストアップ、バッテリー切れ時のメンテナンスコスト等が掛かる。
・eFUSE
不揮発性メモリで、バックアップ用電源は不要。ただし、原則1回しか書き込みできない。
正確には、'0'のビットを'1'に書き換えることはできるが、一度'1'にしたビットは'0'に戻せないという意味。
1回目の書き込みで'0'のままだったビットを、2回目の書き込みで'1'にすることは可能。
AMDの資料では、1回しか書けないという注意書きと併せて、複数に分けて書き込むという文章が混載しており、ややわかりにくい。
2回目の書き込みはワーニングも出るため、1回で済ませた方が無難。
ここでは、eFUSEを使用した方法を紹介する。
3. eFUSE の設定値
3-1. eFUSE 設定値の考え方
eFUSEには、暗号キーを記録する以外に様々な機能があるため、あらかじめ何をしたいのかを明確に決めておかないと、設定で戸惑うことになる。
ここでは、「ビットストリームを暗号化して保護できれば良い」という考え方で設定を検討する。
逆に言えば、保護以外の機能はできるだけ「許可したまま」とする。
3-2. eFUSE 全体構成
eFUSEの全体構成は以下の通り。 ※AMD資料より引用 https://docs.amd.com/v/u/ja-JP/ug470_7Series_Config
・FUSE_KEY 256ビット AESキー、ユーザーが値を決める。
・FUSE_USER 32ビット 任意、特に指定しなくてもよい。(デフォルト は ALL 0 )
・FUSE_DNA 64ビット デバイス固有のID。とりあえずここでは考えなくてもよい。
・FUSE_CNTL 14ビット eFUSE 制御レジスタ、後述
3-3. eFUSE 制御レジスタ
eFUSE の制御レジスタの機能は以下の通り。※同じくAMD資料より引用
・CFG_AES_only 今回は'0' のまま。 ※eFUSE 書き込み後でも非暗号化ビットストリームは自由に書き込めるようにしておく。
・AES_Exclusive 今回は必要ないため'0' のまま。
・W_EN_B_Key_User 今回は必要ないため'0' のまま。 ※AESキーを再書き込みされても問題はない。
・R_EN_B_Key 【重要】 AESキーにプロテクトを掛ける必要があるため、'1'に設定する。
・R_EN_B_User 今回は必要ないため'0' のまま。
・W_EN_B_Cntl 今回は必要ないため'0' のまま。 ※たとえ再プログラムされても、'1'を'0'にはもどせない。
以上の設定を決めた上で、以下、暗号化の設定を行っていく。
4. 暗号化ファイル作成手順
暗号化ビットストリームを生成する設定は、基本的には「Generate Bitstream」設定画面で行う。
が、設定後に xdc ファイルが上書きされ再度コンパイルしなおす手間が掛かるため、ここでは以下の手順で行う。
1. 先に xdc ファイルに暗号化設定を記載しておく
2. これをコンパイルし、「Generate Bitstream」設定画面では、確認だけを行う
3. 確認後、暗号化ビットストリームを生成する
まず、プロジェクトをコンパイルする前に xdc ファイルに以下の記述を追加しておく。
・set_property BITSTREAM.ENCRYPTION.ENCRYPT YES [current_design]
=>暗号化を 「有効」 にする指定
・set_property BITSTREAM.ENCRYPTION.ENCRYPTKEYSELECT EFUSE [current_design]
=>eFUSEを使用する指定
・set_property BITSTREAM.ENCRYPTION.KEY0 256'hB4AC3757D3CF --中略-- 0528D6CE7B8A6 [current_design]
=>AES暗号キーの指定。16進数を組み合わせてユーザーが作成する。
文字列の先頭は [256'h]、その後 16進数で 64桁の文字を作成する。ユニークな文字列であればなんでもOK。
作成したらこの値を忘れずに保存しておく。
XDCファイルを作成したら、コンパイルを行い、「IMPLEMENTATISON」まで終わらせる。
【注意】 「IMPLEMENTATISON」を実行しておかないと、この後の「Generate Bitstream」設定にて、暗号化関連設定が表示されない仕様になっている。
コンパイル後、「Generate Bitstream」 を右クリックで開き、先に「-bin file」生成のチェックONを確認し、「Configure additional bitstream setteings.」を開く。
「Encryption」を指定し
・ビットストリーム暗号化が 「YES」
・暗号キーの選択が 「EFUSE」
・XDCファイルで指定した暗号キーが設定されていること
を確認する。確認が出来たら「OK」を押す。
なおここで設定の変更を行うと、XDCファイルを上書きしなければならず、XDCファイルを上書きしたことでコンパイルからやり直す必要がある。
「Generate Bitstream」 を実行し、ビットストリームを生成する。
「.bin」 「.bit」 などの書き込みファイルと共に、暗号化の時にだけ生成される 「.nky」 ファイルがあることを確認する。
このファイルは eFUSE 書き込み時に指定するため、ファイルの場所をメモしておくとよい。
参考:生成された 「.nky」 ファイルの内容は、以下のようになっている。
・KEY 0 ユーザーが設定した AES暗号キー
・Key StartCBC 自動で生成される。(暗号化で使用される CBC 初期化ベクター)
・Key HMAC 自動で生成される。(データの改ざん確認キー)
5. eFUSE書き込み
PC と Cmod A7-35T をUSBで接続し、[Open Target] から [Auto Connect] を実行する。
[HARDWARE MANAGER] のデバイス名で右クリックしてメニューを表示し、[Program eFUESE Registers] を実行。
[NEXT] を押す。
[.nky]ファイル指定にて、先に生成した [.nky] ファイルを指定する。
AESキーの値を確認する。
USERビットの設定は任意。
確認したら[NEXT]を押す。
必須ではないが、[.nkz] ファイルの保存場所を指定しておく。ここで指定しておかないと、後で探すのに苦労する。
プロジェクトファイルと同じディレクトリを指定しておくのが無難。
※ [.nkz] ファイルは、GUI操作での暗号化手順では使用しないが、TCLコンソールからの eFUSE 書き込みコマンド「program_hw_device」で使用できる。
ただし今回は試していない。
書き込みチェック、ファイル保存先ディレクトリを確認したら [NEXT]。
[Finish]ボタンをおす。
最終確認[OK]ボタンをおす。
eFUSE の書き込み成功すれば、コンソールに書き込み成功のメッセージが表示される。
6. コンフィグレーションROMの書き込み
[HARDWARE MANAGER] から右クリックでメニューを表示し、[Add Configration Memory Device..] を選択する。
基板に実装しているコンフィグレーションメモリの型番を指定する。
手元にある「 Digilent Inc. 製 Cmod A7-35T」では [MX25L3273F] だが、製造時期によって異なるため、手持ちの基板を確認すること。
「今すぐ書き込むか?」と尋ねてくるので、[OK」を押す。
コンフィグレーションメモリに書き込む [.bin] ファイルを指定する。
書き込みが終わると、「デバイス名が指定されていない」というワーニングが出るが、書き込み自体は成功しているため無視して「OK」を押す。
※eFUSE を使用した場合に発生するワーニングらしいが、今現在、ワーニングを消す方法は見つかっていない。
以上の作業が成功していれば、Cmod A7-35T のUSBコネクタを差し直すことで、緑のLEDが点滅する。
7. サンプルファイル
【注意】 eFUSE は一度書き込んだら元に戻せないため、実機テストは慎重に。
・VIVADO用プロジェクトファイル:japanlogicdesign_vhdl_tips_artix_7a_led_blink_encryption.zip
※VIVADO のバージョンが異なる可能性があるため、プロジェクトファイルは新規に作成することを推奨する
中国プロテクト:天安門事件、法輪功、チベット
|