文章にする時間がないので箇条書きで。
まとめ
- ARMv8.3-Aの拡張仕様の1つ
- 目的は攻撃者によるポインタ書き換えの検出
- たぶんソフトウェアでも実装できるが、より安全で高速だと思われる
- 性能評価結果はないのでどの程度性能が良いのかは不明
- たぶんソフトウェアでも実装できるが、より安全で高速だと思われる
- 攻撃者には生成できない認証コードをポインタに埋め込む
- Aarch64だと仮想アドレスの一部は使われていないのでそこを利用する
- このプレゼン資料(pdf)にアドレスのレイアウトの図がある
- 認証コードが埋め込まれたポインタは不正な仮想アドレスになる
- ポインタ利用時には認証コードを検証し認証コードを削る
- 認証に失敗したときはポインタ内の認証コード部分を壊すので、実際にポインタを利用しようとすると不正なアドレスとなり例外が発生しプログラムの実行が止まる
- Aarch64だと仮想アドレスの一部は使われていないのでそこを利用する
- 認証コードの生成にはポインタ自体、秘密鍵、もう一つの何か(例:スタックポインタ)を用いる
- 秘密鍵はシステムレジスタに保持され攻撃者はアクセスできない
- 後述の新規命令でのみ利用できる
- 5種類の鍵が存在するが違いはあまり理解していない(Linuxは1つしか使っていない)
- 認証コードを生成するアルゴリズムはQARMA
- 秘密鍵はシステムレジスタに保持され攻撃者はアクセスできない
- 専用命令
- ポインタに認証コードを付加するpac命令, 認証コードを検証してポインタを元に戻すaut命令がある
- CPUに機能がない場合だとNOP扱いになる命令(例:paciasp)と、通常の命令(例:pacia)が存在する
- 最初は前者のみサポート
- 実際の使われ方はこのプレゼン資料(pdf)を参照
- Linux 5.0でカーネル側のサポート機能が入る
- exec時に秘密鍵を設定したり、コンテキストスイッチ時に鍵を切り替えたりする
- 5.0ではポインタ認証が使えるのはユーザプロセスのみでカーネルでは使えない
- コンパイラのオプションで上記命令を埋め込むことでポインタ認証をプログラムで利用する
- GCCだと-msign-return-address
- 引数は不明だがLLVMも対応ずみらしい
参考資料
- ARM pointer authentication [LWN.net]
- arm64: docs: document pointer authentication
- 6.5.4. Hint instructions
- 16.24 AUTIA, AUTIZA, AUTIA1716, AUTIASP, AUTIAZ
- ARMv8.3 Pointer Authentication (pdf)
- Pointer Authentication on ARMv8.3: Design and Analysis of the New Software Security Instructions (pdf)
- [AArch64] Enable ARMv8.3-A pointer authentication
- The QARMA Block Cipher Family