さて、次が基調講演でも出てきたTrustZoneの話になる。基本的には既存のTrustZoneと同じ「コンセプト」である(Photo06)。具体的に言えば、ARMv8-Mでは「Secure Mode」と「Non Secure Mode」という2つの動作モードが新たに設けられた。もっともこのSecure Modeを設けるにあたり、追加されるリソースは本当に最小限である。例えばレジスタ類を新設することすらしていない。ではこれでどうやってTrustZoneを実現できるのか?。

Photo06:元々のコンセプトとは、セキュアな領域を別に設け、そこでセキュアな処理を別に行う、というものである。これを何とかして1つのMCU内で完結させた、というのが今回の実装。ちなみに当然ながらこれはオプション扱いである

まずプログラマから見たメモリマップがPhoto08である。これはNon Secure Modeから見た構図であるが、セキュアな領域はMPUによって保護されるので、「基本」アクセスが一切出来ないことになる。

Photo07:Handler Modeとは要するに割り込みの処理を行うISR動作状態を指し、Thread Modeは通常の動作状態となる

Photo08:これは従来のMPUでも基本的には同じであるが、システム領域においても細かくMPUでアクセスできない領域を設けている点が異なる

一方、Secure ModeにおいてはこのSecure Unitにアクセスが可能である。「基本」と書くのは例外があるからで、Photo09の赤い部分は、NCU(Non-Secure Callable)と定義される。NCUはおおむね、簡単なエントリポイントなどが置かれる程度のものだが、要するにNormal StateからSecure Stateを呼び出す際に利用される領域として定義される。

Photo09:セキュア領域に関して言えば、システム全体で言えばSAU(Secure Attribute Unit)とIDAU(Implementation Defined Attribution Unit)があり、このIDAU経由でCPU外のセキュアなユニットを領域に指定することも可能となっている

さて、もう少し先に進んでみる。Non Secureで稼働中にThread→Handler、あるいはHandler→Secureの遷移はこれまでと同様だし、Secureで稼働中も同じである。ではNon Secure Thread中にSecureなインタラプトが入った(あるいはSecure Thread中にNon-Secureなインタラプトが入った)らどうなるか、がPhoto10となる。扱いとしてはARMv7-MのException Handlingと同じ仕組みとすることである。遷移の際にかならずZero Clearするのは、これによるSnoopの可能性を抑えるためである。

Photo10:逆にNon Secure StateからSecure Stateに戻る場合はZero Clearは必要ないと判断しているようだ。このあたりは割り切りなのであろう

ちなみにSecureかNon Secureかの区別は、基本的にはアドレスベースでの管理となる。これを管理するのが(Photo09のキャプションにも出てきている)SAUで、ここがメモリ領域ごとにSecureかNon Secureかの情報を格納している(Photo11)。なので、Non Secure StateのアプリケーションがSecureなアドレスにアクセスしようとすると、Memory Faultを発生する形でSecureが担保される。ちなみにBranch/CallでSecure Addressをアクセスしようとした場合は、新しく追加されたSecure Fault(Exception Number 7)が発生する形だ。

Photo11:逆に言えば、SAUを攻略するのがマルウェアの最初の一手ということになるが、このあたりをどう防ぐかはインプリメントの話になるためか、今回は説明はなかった

このあたりをもう少し見やすくしたのがPhoto12で、Secure State/Non Secure-State、Secure Address/Non-Secure Addressは完全に分離されており、唯一NSCの領域でのみ両者がアクセスできる事になる。もっとも分離されているといっても、お互いの呼び出しは自由に可能である(Photo13)。Thread同士で呼び出す場合はこんな具合だ(Photo14)。この場合呼び出されたSecure Thread側はまずSGでSecure Modeに切り替わり、その後Secure Codeを実行、最後にBXNSでNon-Secure Modeに戻る形になる。ちなみにExample(Photo15)などにはまだ具体的なコード記述の仕方などが示されていないが、恐らくPhoto10と同じように、BXNSを呼び出す前に(戻り先と戻り値以外の)RegisterはZeroクリアするような作法が入るのではないかと思われる。

Photo12:つまり一度ロードを行い、SAU(なりIDAU)がメモリ領域の設定を行ったあとは、きちんとSecure ModeとNon-Secure Modeが分離される訳で、あとは最初のロード時を狙うかSAUにアタックするしかないことになる

ちなみにARMv8-Mの場合、TrusuZoneをインプリメントしないとNon-Secure Modeで起動するが、インプリメントした場合は無条件でSecure Modeでの起動となる。なのでアプリケーションもSecure ModeでSystem Startを記述する必要がある(Photo16)。

Photo13:この図はちょっと不正確なところがあり、Handler同士はCall/Return以外にIRQもサポートする。もちろんThread同士だとCall/Returnしかないのだが。またHandler/Thread間は(Secure Mode内/Non-Secure Mode内でも)やはりIRQ/Returnとなる

Photo14:BXNSは今回追加されたもので、BX(命令セット切り替え付き分岐)にNS(Non-Secure)オプションが組み合わされたもの

Photo15:Secure Functionの記述法。気になるのは、例えば構造体のアドレスを渡すとか、結果も構造体を返すというような、要するにレジスタではなくデータ渡しとなるケースで、Photo09におけるNon-Secure MPU aliasの中にそのコピーを作って渡すような形になるのかもしれない

Photo16:アプリケーション構図。実際はInterruptも入るのでもっと複雑だと思うが