Secure Enclave Processor (SEP)
2025/3/9時点のsepの翻訳
過去のコミュニティでの調査とSEPの掘り下げに基づいたSEPに関するいくつかのメモです。Asahi Linux 上の SEP をトレースしたい人のための TODO も加えています。
公正な警告:きれいなページを作成するのに十分な理解が得られるまでこのページは乱雑でこのまま維持されます
Asahi をトレースする人への注意事項
ロードされる SEP ファームウェアをコントロールすることはできないので、Linux 自体にとって重要な部分は、他の ASC と同様、AP と SEP 間の通信プロトコルだけです。 xART/Gigalocker の作成とプロビジョニングフローを理解するために、新しいユーザーを作成すると、そのユーザーのために新しい暗号鍵が用意されます。 また、言うまでもないことですが、トレースは Asahi Linux のファームウェアと同じmacOSのバージョンで行う必要があります(2024/11/13時点でバージョン13.5)。- 完全に正しいわけではありません。SEPファームウェアは、デバイスにインストールされた最大バージョンのmacosによって決定されますが、プロトコルは後方互換性があります。
トレースのTODO
- Python コンソール上でのトレーサーからのメッセージスパムを大幅に減らす。このメッセージスパムはシステムを大幅に遅くし、時にはパニックに陥ることも
- 現時点でトレーサーは Monterey または Big Sur の SEP ファームウェアを想定。Venturra 以降に更新する必要あり
- おそらく、エンドポイントインデックスに基づいて、個々の SEP アプレットからの SEP メッセージのみをトレース。別の Python スクリプトを使用して SKS フローまたは SSE フローをトレースできるようにすべき
- すべてのエンドポイント用にメッセージタイプと送信データのテーブルを構る(XNU ログでは多くのメッセージは真の SEP メッセージの一部がマスク)
その他の質問
- デバッグエンドポイントがエンドポイントが起動したことを AP に通知するとき、『DATA』 フィールドの値が 0x2020202、0x10101、0x0、または 0x2020404 になる
- これは入力と出力のページ単位でのバッファサイズ。なぜ2倍になっているのかは不明
- エンドポイントのセットアップ中に、SEPの共有メモバッファの最初の32ビットワードの下位バイトが02から1fに変更。コンフィギュレーション・ビットなのか、macOS や SEP OS が変更している?
コプロセッサ情報:
DCPのような他の ASC コプロセッサと同様に、これはASCコプロセッサであるため、同じようなメールボックスインターフェイスと場合によっては 使用される共有バッファ(AppleSEPManagerでは、これらを 『OOL』バッファと呼び、おそらくラインバッファから外れている)を通じて コミュニケーションします。RTKitまたはその派生を実行する他のプロセッサとは異なり、SEPはAppleが内部的にSEPOSと呼ぶカスタムOSを 実行しているらしいです。さらにSEPOS自体は、SEP自体で動作する多くの異なるアプリケーションに分割されているらしいです。
SEPは自身のファームウェアを認証するようで(SEPがIMG4を『accept』したというカーネルの文字列が証明)、ファームウェアの認証に 失敗するとパニックになるようです。SEP ファームウェアは、通常の AP の GID とは別の GID によって暗号化されているため、 iBoot のbootchain vulnは、SEP 自体を侵害しない限り、SEP ファームウェアを復号化したり、任意の SEP ファームウェアを ロードしたりすることはできません。
他の ASC コプロセッサーと比較すると、SEP はデバイス上の他のプロセッサーがアクセスできない(少なくともラップされたキーなどの 機密情報用の)専用のストレージを持っていると思われる唯一のものです。
T8112 ASC SEP メールボックスのベース: 0x25E400000 (実際のメールボックスは他のASC IOPと同様に+0x8000)
エンドポイント情報:
エンドポイント番号 | エンドポイント名 | 目的 |
---|---|---|
0x00 | Control/CNTL | エンドポイントプロパティを制御するようにみえる |
0x08 | Secure Biometrics (SBIO) | 生体認証 |
0x0a | SCRD | ユーザ権限認証に使われる『セキュリティ/SEP 権限マネージャ』らしい? |
0x0c | sse | 何らかの形で NFC に関連。Apple Pay に関連するかも |
0x0e | HDCP | HDCPコンテンツ保護らしい |
0x10 | xars (トレーサーより) | xART セットアップ? スタートアップ・シャットダウン関連 |
0x12 | Secure/SEP Key Store | SEP 暗号化・復号操作と鍵管理 |
0x13 | xART manager | xARTsとgigalockersとkeybagsの管理(SKSを開始するの必要)needed for SKS to start) |
0x14 | hibe (トレーサーより) | ハイバネーション関連 |
0x15 | pnon (トレーサー名) | ブートポリシー関連。いずれはマシン所有者の認証情報のハンドオフのために必要だが、今は無視してもよい |
0x17 | skdl | CoreKDL。KDL は kext deny list の略で、FairPlay に関連し、HDCP や Apple Pay にも関連するかも |
0x18 | stac | AppleTrustedAccessory拡張にリンク、おそらく『Secure/SEP Trusted Accessory Connection』 |
0xFD | Debug(?) | 発見的なエンドポイント、エンドポイントリストとOOLバッファサイズを返す |
0xFE | Boot254 | 保護されたメモリ領域にセットアップされる IMG4 で SEP が SEPOS にブートするように SEP に信号を送信 |
0xFF | Boot255 | ブートを進めるためにBootTZ0メッセージ経由でSEPに信号を送信 |
Gigalocker/xART フォーマット(この情報を提供してくれたsven氏に感謝!): | セクション開始-セクション終了 | 説明 | | ------------------------- | ----------- | | 0x00-0x01 | 常に0 (おそらく何らかのバージョン識別子?) | | 0x01-0x12 | UUID/キー (SKSのキー識別子?) | | 0x12-0x16 | キーの長さlength of key | | 0x16-0x1a | ラップしたキーのCRC | | 0x1a-0x22 | 目的不明| | 0x22-ペイロードの終端 | ペイロード・ラップしたkeybagデータ |
基本的にSEPによって更新されるキー/バリューストア(keybagデータが格納される場所)。
SEP メッセージの形式:
bits 0-7 - エンドポイント番号
bits 8-15 - 『タグ』値 (制御エンドポイントの場合、受信メッセージと送信メッセージがタグを共有する場合があるが、SEP ブートロムではあまり使われない)
bits 16-24 - メッセージ『タイプ』(受信側で何を動作させたいかであり、このフィールドは SEP に希望する動作を伝える手段)
bits 25-31 - メッセージパラメータ(デバッグエンドポイント、これは常にデバッグエンドポイントが応答・情報受信しているエンドポイントで、SEP ブートロムではあまり使われない)
bits 32-63 - 何らかのデータ(ポインタでも設定値でもかまいませんが、システム状態を変更するアクションでは、ほとんどの場合、設定する必要あり)
メールボックスは127-63ビットにあるものを送信することができますが、現在、これらのビットは未使用で、SEP ブーロロムはそれらを完全に無視し、 AppleSEPManagerもそれを行いません。
SEPブートフロー:
- iBoot が ADT に記録されているメモリ領域に SEP ファームウェアをプリロード
- XNU が bootz0 メッセージを送信し、SEP を第2段階のブートに移行させる(RAM の一部はこのために予約)
- XNU が img4 を送信し、SEP は整合性を検証し、受け入れられた場合は SEP/OS にブート(不正なまたは無効な img4 を送信するとSEP 側でパニックが発生し、機器がリセットされるまで、そのブートの残りの部分は使用不能に)
- エンドポイントを設定(xART/Gigalocker 設定、FileVault キーなどの SKS セットアップを含む)
xART initフロー(現時点では不完全であり間違っているかも):
(メッセージタイプ0は何らかのフェッチリクエスト、メッセージタイプ0x5は個々のlockerに対するフェッチ応答と思われる) (タグはgigalocker内のlockerの順番で増えていくらしい)
```c: //Gigalockerの初期化 (TODO: 以後のOSバージョンで同じフォーマットが使われるか確認)
[cpu1] [SEPTracer@/arm-io/sep] [xarm] >0x0(None) 0000010000000213 (EP=0x13, TAG=0x2, TYPE=0x0, PARAM=0x0, DATA=0x100)
[cpu14] [SEPTracer@/arm-io/sep] [xarm] <0x13(None) 0000000000130113 (EP=0x13, TAG=0x1, TYPE=0x13, PARAM=0x0, DATA=0x0
//SEP xARTをgigalockerから取得(このxART自体が多くのsublockerを持っているらしい?)
[cpu0] [SEPTracer@/arm-io/sep] [xarm] >0x0(None) 0000000000000113 (EP=0x13, TAG=0x1, TYPE=0x0, PARAM=0x0, DATA=0x0)
[cpu10] [SEPTracer@/arm-io/sep] [xarm] <0x0(None) 0000010000000313 (EP=0x13, TAG=0x3, TYPE=0x0, PARAM=0x0, DATA=0x100)
SEPトラストアクセサリーの注記:
```c:
//ping
[cpu0] [SEPTracer@/arm-io/sep] [stac] >0xf(None) 00000000000ffc18 (EP=0x18, TAG=0xfc, TYPE=0xf, PARAM=0x0, DATA=0x0)
//pong
[cpu0] [SEPTracer@/arm-io/sep] [stac] <0xf(None) 00000000000ffc18 (EP=0x18, TAG=0xfc, TYPE=0xf, PARAM=0x0, DATA=0x0)
AppleTrustedAccessoryはおそらく外部キーボード上のタッチIDセンサーに対してこのエンドポイントと対話します。
SEP後方互換性に関する注記:
SKS IPCはカーネル側とSEP側の両方でネゴシエートされ、両者間で最も互換性の低いバージョンが、メインプロセッサとSEP間の通信に使用されるIPCとなります。
これにより、SEPがアップグレードされても、SEPとOSの互換性が保たれるはずです(古いIPCバージョンが使用されるだけなので)。(潜在的疑問: Linuxドライバではこれをどのように説明すべき?)
その他の注釈:
制御エンドポイントは、何かが成功した場合、0x1 のメッセージタイプと入力パラメータで入ってくるリクエストに応答するようです(すべてが順調であれば、SEP 側から ack/okay が来るはず)(少なくとも、入力/出力の長さやポインタを設定するメッセージの場合)。
SKSは通常モードでは、sepをエンドポイントとするメールボックスメッセージが常に送信されるため、非常にスパム的です(これは、Appleセキュリティガイドによると、データ保護の仕組みが原因で、これらの多くはgigalockerから/への鍵を取得/更新している可能性大)。
シングルユーザーモードはトレースする際に有用です。SKS がほぼスパムにならず、初期化シーケンスを捕捉することができるからです。
xART フェッチメモ:
ロッカーのフェッチシーケンス中は、多くのメッセージは『データ』部分として 0x100 をもちます。 ロッカーのフェッチ/アンラップ要求に関する SEP からの応答は、常にパラメータ 0x10 をもちます。 タイプ 0x5 の応答は成功、0x7 はエラーです(これは最低でもユーザーxART ロッカーが見つからなかったことを示すエラー)。