DeepCoverセキュアマイクロコントローラ(MAXQ1103)用の破壊的リセット診断ルーチン
要約
DeepCover®セキュアマイクロコントローラ(MAXQ1103)は、多数のタンパ検出入力のいずれかがトリガされると機密データの消去を行います。破壊的リセットの後、リカバリベクタによって診断コードを実行して、破壊的イベントに関する適切なログや通知に必要となる追加の作業を行うことが可能です。このアプリケーションノートでは、Rowley CrossWorks Cコンパイラを使用した診断ルーチン作成の様々な側面について検討します。
このアプリケーションノートで使用しているソースコードのダウンロードが可能です(ZIP)。
はじめに
DeepCover®セキュアマイクロコントローラ(MAXQ1103)は、物理的タンパとそれに続く貴重なデータの漏えいを防止するための多数の重要な機能を実装しています。それらの機能の1つが、Destructive Reset Source (破壊的リセットソース)、略してDRSサブシステムです。DRS機能は、複数の自己消滅入力(SDI)のいずれか1つによって、プログラムおよびデータ復号化キーと内蔵スタティックRAMをほぼ瞬時に消去するものです。アプリケーションが内蔵プログラムフラッシュメモリ内の暗号化領域に格納されている場合、プログラム復号化キーの消去によってマイクロコントローラが動作しなくなります。
以前のマキシム製品(DS5250など)にも、このDRS機能が組み込まれていました。しかしMAXQ1103では、破壊的リセットの後で非暗号化診断ルーチンを実行する機能が追加されています。この診断ルーチンでは、(次回のパワーオンリセットまでディセーブルされている)外部メモリバスへのアクセスを必要としない、任意の非暗号化内部コードを実行することができます。
例として、診断ルーチンを使用してモデム経由で中央のオフィスにメンテナンスアラートを送信するとともに、ユーザーに対して「故障中」の表示を行うことができます。このルーチンでは、内蔵フラッシュメモリの消去と再プログラムも行います。
DRS診断ルーチンの設定
DRS診断ルーチンは、DRSRSレジスタのビット位置DIAEでイネーブルします。DRSRSレジスタのビットDIAS[3:0]で、原因となったSDIがクリアされた後にマイクロコントローラのジャンプ先ベクタとなるプログラムコードの位置を指定します。診断ベクタの位置が暗号化メモリ領域を指している場合、リセット後にマイクロコントローラのROMが単にプロセッサを停止させます。それがDIAE=0 (診断ルーチンがイネーブルされていない状態)でのデフォルトの動作です。
DRSRSレジスタは、通常のプログラム実行中にいつでも書き込むことができます。このレジスタには、破壊的リセットのソースを示すフラグも確保されています。診断ルーチンでこれらのフラグを使用したり、不揮発性メモリにロギングしたりすることができます。
アプリケーション例:安全なクロック
MAXQ1103のDRSルーチンの実例を示すために、Rowley CrossWorksコンパイラを利用して、C言語で小さいアプリケーションを作成しました。このアプリケーションは、MAXQ1103 EV kit (Rev D)で簡単なリアルタイムクロック(RTC)を実装するものです。
EVキットのLCDに日付と時刻が継続的に表示され、毎秒更新されます。キットの数値キーパッドのENTキーを使用して、ユーザーが日付と時刻を直接入力することができます。日付と時刻のフィールド間をカーソルが自動的に移動します。表示例を図1に示します。
SDI入力端子のいずれかがハイ(VDDIO)に駆動された後で解放されると、マイクロコントローラは破壊的リセットを実行します。このリセットによってプログラム復号化キーが消去され、メインプログラムコードが動作しなくなります。代わりに、DRSが発生したことを示すメッセージとDRSRSレジスタの内容がLCDに表示されます。図2を参照してください。
DRSRSレジスタ内のフラグを使用して、どのSDIソースが破壊的リセットの原因となったかが解析されます。さらに、最新のDRSの時刻と日付がLCDディスプレイに表示されます。この最後の機能は、厳密にはDRS診断ルーチンの一部ではなく、SDIが発生した瞬間にRTS (RTC Second Counter)レジスタの値を捕捉するDRSロガーです。
実装の詳細
RTCの「メインアプリケーション」を実行するソースコードは簡単な内容であるため、このアプリケーションノートでは解説しません。しかし、このソースコードには詳細なコメントが記述されており、RTCの例として再利用することが可能です。このコードセクションは、プログラムメモリアドレス0x000600から始まるCODEという名前のメモリセグメントに格納されます。MAXQ30_Target.jsスクリプトに含まれるプリプログラムロードコマンドが、PMACおよびPMSZレジスタを使用して64kワードの暗号化領域をイネーブルします。この領域は3DESで暗号化されており、CODEプログラムセクションが格納される場所になります。
DRSのリカバリベクタを実装するには、メインアプリケーションプログラムによって使用されないスペースを確保する必要があります。ファイルMAXQ1103.xmlの中で0x3C600から始まる16kワードのメモリセクションが宣言されており、その中にRESERVEというメモリセグメントが宣言されています。これによって、Rowleyのアセンブリ言語ディレクティブCSEG RECOVERYを使用してDRS診断ルーチンを適切なアドレスに配置することが可能になっています。このアドレスは、DRSRSレジスタ内のDIAS[3:0]ビットによって決定されます。
関数enable_drs_diag()は、DRSRSレジスタに0x00001E01という値を書き込みます。この値は診断ベクタをイネーブルして、診断ベクタの位置として0x3C600を選択します。
DRS診断ルーチンは、破壊的リセットの後で(すなわち原因となった自己消滅入力が除去された時点で) ROMによって呼び出されます。このルーチンでは、(PMAC/PMSZによって定義される)暗号化メモリ領域内にある他のコードを呼び出すことはできません。そのコードは暗号化状態でフェッチされることになり、その結果の実行によって意図しないシステム動作が発生する可能性があります。
リカバリルーチンはファイルdrs.asmに含まれており、CSEGディレクティブを使用してこのコードをRECOVERYセグメントに配置する方法を示しています。
診断ベクタは内蔵プログラムメモリの非暗号化Cコードを呼び出すことができますが、そのコードを呼び出す前にプログラマがCランタイム環境のセットアップを行っておく必要があります。どのようなセットアップが必要かは、Rowleyコンパイラに含まれているcrt0.asmファイルを参照して判断することができます。
結論
MAXQ1103の診断ルーチン機能は、セキュリティ関連の破壊的リセットに続いてコードを実行する手段をアプリケーションプログラマに提供します。それによって、安全なアプリケーションと安全が確保されていないリカバリコードとが明確に分離されます。その後、診断ルーチンでセキュリティ侵害をロギングしたり、遠隔地へのアラート通知やさらなる内部メモリ消去の実施などの適切な破壊後の作業を行ったりすることができます。