このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
本記事では、TEE (Trusted Execution Environment) の基礎知識については触れませんが、「TEE」「TrustZone TEE」などの単語で検索して事前学習いただくと記事内容を理解しやすいと思います。
TEE (Trusted Execution Environment) とは、SoC 的に隔離された環境で安全にプログラム (TA: Trusted Application) を実行できる機能です。
応用例としては、秘密計算のオフローディング、暗復号の鍵管理、セキュアドライバ等が挙げられます。
現時点で TEE を実現できる HW 機能は以下の三種類があります。
ARM TrustZone 制御の実装は各社から提供されており、いくつか例を挙げると、
Kinibi は Trustonic 社が提供する TrustZone 制御の実装です。 以下のような特徴を持ち、PKCS#11、EVITA HSM、AutoSAR crypto API の代替手段として用いることが可能です。
Kinibi の起動は、SecureBoot フローに沿って行われます。 SecureBoot は、BootLoader が次に実行する BootLoader の安全性を Signature を用いて確認してから起動するものです。 Kinibi のプログラム自体が改変されていないことを SecureBoot で保証します。 ARM Cortex-A のブートフローは BL1、BL2、BL3 (BL31、BL32、BL33) の3段階に分かれています。
Kinibi のプログラムは SWd (Secure World) の TA (Trusted Application) と、NWd (Normal World) の CA (Client Application) に分かれています。 CA は TA に対して、Secure Monitor Call (SMC) 命令を発行して TA の処理を呼び出します。 SMC は EL1 (Kernel) を介して発行され、EL3 (Secure Monitor) で処理されます。 World 切替 (SWd NWd) は必ず EL3 を経由し、EL1 (NWd) で動作している CPU が直接 EL1 (SWd) に遷移する、といったことはありません。 また、データは NWd Memory (Normal Memory) に確保された Shared Memory (図中の Buffer#1 …) を介してやり取りされます。 (基本的に引数に対して一つの Buffer を使用) CA が TA を呼び出す際のコマンド及び引数は NWd Memory に格納されており、これを SWd の TA が参照します。 TA のデータは SWd Memory (Secure Memory) に格納され、必要に応じて Shared Memory にコピーされて CA に返却されます。
以下で使用している API 一覧
機能 | API | シグネチャ | 概要 |
---|---|---|---|
初期化 | TEEC_InitializeContext |
TEEC_Result TEEC_InitializeContext(const char* name, TEEC_Context* context) |
TEE
実行に必要なコンテキストを取得(初期化)します この API 終了時点では、まだ TA は起動していません |
セッション開始 | TEEC_OpenSession |
TEEC_Result TEEC_OpenSession (TEEC_Context* context, TEEC_Session* session, const TEEC_UUID* destination, uint32_t connectionMethod, const void* connectionData, TEEC_Operation* operation, uint32_t* returnOrigin) |
TA を起動・初期化して、呼び出し元の CA
と紐づけます。以降、起動した TA はセッション TEEC_Session
を指定することで呼び出せます |
メモリ領域確保 | TEEC_AllocateSharedMemory |
TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context* context, TEEC_SharedMemory* sharedMem) |
Swd/Nwd のデータ授受に用いるバッファを確保し、コンテキストに紐づけます |
コマンド実行 | TEEC_InvokeCommand |
void TEEC_CloseSession (TEEC_Session* session) |
TEEC_Session で指定された TA
の処理を呼び出します。引数は必要に応じて TEEC_Session
に紐づけておきます |
メモリ領域解放 | TEEC_ReleaseSharedMemory |
void TEEC_ReleaseSharedMemory (TEEC_SharedMemory* sharedMem) |
TEEC_AllocateSharedMemory
で確保したバッファを解放します |
セッション終了 | TEEC_CloseSession |
void TEEC_CloseSession (TEEC_Session* session) |
TEEC_OpenSession
で取得したセッションを終了し、TA をアンロードします |
終了 | TEEC_FinalizeContext |
void TEEC_FinalizeContext(TEEC_Context* context) |
TEEC_InitializeContext
で取得されていたコンテキストを終了し、破棄処理を行います |
使用API:TEEC_InitializeContext
TA
を開始する前に、TEE 実行環境を確認して実行コンテキスト
TEEC_Context
を初期化します。 具体的には、実行可能な TEE
の種類、ドライバのバージョンなどを確認します。
バージョンを確認する理由は、想定より古いバージョンにはバグが残っている可能性があるためです。
使用API:TEEC_OpenSession
TA をロードして、TA
を論理コンテナ TEEC_Session
に紐づけます。 本処理の中で、TA
は Secure Memory にロードされて初期化されます。 以降、起動した TA は
TEEC_Session
で指定します。
使用API:TEEC_AllocateSharedMemory
CA と TA
は、プロセス間通信と同じくスタックやヒープを共有していないため、データ授受を
Normal Memory を介して行います。
基本的に、呼び出しの際に使用する引数一つに対して一つ確保します。
確保されたバッファは TEEC_Context
に紐づけられます。
使用API:TEEC_InvokeCommand
CA から TA
の処理を呼び出すには、TEEC_InvokeCommand
API を使用します。
引数を TEEC_AllocateSharedMemory
で確保した領域に格納した後、TA 処理の ID を指定して呼び出します。 この
ID は、呼び出す処理 (≒実行する TA 内関数) を指定するもので、TA
内で一意であるべきですが、値は CA/TA
で共有されていれば大きな制限は問題ありません。 CA → TA
の実行遷移は、SMC
命令によって実現されます。 TA
は指定された処理が終わると ERET
命令で CA
に処理を戻します。 SMC は同期例外のため、一度 TA に処理が移ると、TA
の処理が終わるまで CA に処理が戻ることはありません。
使用API:TEEC_ReleaseSharedMemory
TEEC_AllocateSharedMemory
で確保した領域は、使用後に
TEEC_ReleaseSharedMemory
で解放します。
使用API:TEEC_CloseSession
TEEC_OpenSession
で開始した TEEC_Session
を破棄します。 本処理の中で、TEEC_Session
に紐づけられた TA
は終了処理が実行され、アンロードされます。
使用API:TEEC_FinalizeContext
TEEC_InitializeContext
で生成した実行コンテキスト
TEEC_Context
を終了し、破棄します。
keisuke.kimura in Livox Mid-360をROS1/ROS2で動かしてみた
Sorry for the delay in replying. I have done SLAM (FAST_LIO) with Livox MID360, but for various reasons I have not be...
Miya in ウエハースケールエンジン向けSimulated Annealingを複数タイルによる並列化で実装しました
作成されたプロファイラがとても良さそうです :) ぜひ詳細を書いていただきたいです!...
Deivaprakash in Livox Mid-360をROS1/ROS2で動かしてみた
Hey guys myself deiva from India currently i am working in this Livox MID360 and eager to knwo whether you have done the...
岩崎システム設計 岩崎 満 in Alveo U50で10G Ethernetを試してみる
仕事の都合で、検索を行い、御社サイトにたどりつきました。 内容は大変参考になりま...
Prabuddhi Wariyapperuma in Livox Mid-360をROS1/ROS2で動かしてみた
This issue was sorted....