i.MX 93 AHABの署名と認証の仕組み¶
i.MX 93プロセッサのAdvanced High Assurance Boot (AHAB)の署名と認証の仕組みを説明します。
i.MX 93の起動ファイルは固有のコンテナ形式になっています。 AHABを使用したセキュアブートでは、コンテナに公開鍵と署名を付加し、デバイス起動時にはコンテナに含まれている公開鍵を認証し、コンテナの内容が改変されていないか検証することで、不正なソフトウェアの起動を防ぐことができます。
1. イメージのコンテナ化¶
Fig. 1 イメージのコンテナ化¶
i.MX 93のBOOTROMやU-Bootがメモリにロードして使用するイメージは、あらかじめコンテナ形式に変換しておく必要があります。
Note
ここでイメージと言っているのは、U-Boot-SPL, U-Boot, ATF, OPTEE, M-Core SW, Kernel, DTB, Ramdisk, その他メモリ上に配置したいデータ等のことです。
コンテナ形式の詳細は i.MX 93 Applications Processor Reference Manual のSystem Bootの章にに記載があります。
イメージをコンテナ化するには、 imx-mkimage と、それに含まれる mkimage_imx8 というツールを使用します。
コンテナを生成すると、コンテナファイルの先頭にはContainer Headerが付加されます。この中には各イメージのオフセット、サイズ、ハッシュ値などを集めたImageArray、セキュアブートのため公開鍵、署名を書き込むSignature Blockなどがあります。Signature Blockは、ほぼ空の状態で生成されます。
複数のイメージを一つのコンテナにすることができます。イメージのデータはコンテナファイルの一番後ろに連結されます。
2. コンテナに公開鍵と署名を付加¶
Fig. 2 コンテナに公開鍵と署名を付加¶
i.MX 93デバイスで意図しないコンテナを使用されないよう、また、コンテナの内容の改変を検知できるよう、Code Signing Tool(以下、CST)を使用して、コンテナに公開鍵と署名を付加します。
最初にSuper Root Key (以下、SRK)を生成します。
CSTに含まれるスクリプト ahab_pki_tree.sh でCAとSRK1~SRK4を生成します。SRKは公開鍵とプライベート鍵のペアとなっていて、プライベート鍵は秘匿しておく必要があります。
CSTに含まれる srktool を使用して、SRK1~SRK4の4つの公開鍵を連結したSRK Tableを生成します。同時にSRK TableのSHA-256であるSRK Hashも生成されます。 SRK Hashは、i.MX 93デバイスのSRK_HASHヒューズに書き込みます。
SRKはi.MX 93デバイスのライフサイクルが終了するまで長期にわたり保存しておく必要があります。
次に、CSTに含まれる cst でコンテナに公開鍵と署名を付加します。
先ほど生成したSRK Tableは、Signature BlockのSRK Tableフィールドに書き込まれます。
Container Headerの先頭からSRK Tableフィールドの末尾の領域に対して、SRKのプライベート鍵の一つを使用して署名されます。
署名データは、Signature BlockのSignatureフィールドに書き込まれます。
3. 署名付きコンテナの認証¶
Fig. 3 署名付きコンテナの認証¶
最初に、コンテナ上のSRK TableのSHA-256を計算して、i.MX 93デバイスのSRK_HASHヒューズの内容が一致していれば、SRK Tableは署名に使用したSRKと同じ、ということを認証できます。
SRK Tableが認証されれば、次に、SRK Tableの中に含まれるSRK公開鍵と署名データを使用して、Container Headerの先頭からSRK Tableフィールドの末尾の領域が改変されていないかを検証できます。
最後に、Container Headerが改変されていないことが検証できれば、ImageArrayに書かれているHash値と各ImageのHash値を比較することで、イメージが改変されていないかを検証できます。
4. U-Bootでの署名付きコンテナの認証¶
U-Bootでの署名付きコンテナの認証には、U-Bootの auth_cntr コマンドが使用されています。
auth_cntr コマンドが実行されると、do_authenticate関数がコールされ、そこからauthenticate_os_container関数がコールされます。
authenticate_os_container関数から、ahab_auth_cntr_hdr関数とahab_verify_cntr_image関数がコールされます。
ahab_auth_cntr_hdr関数からは、ele_auth_oem_ctnr関数がコールされます。 ahab_verify_cntr_image関数からは、ele_verify_image関数がコールされます。
-
https://github.com/nxp-imx/uboot-imx/blob/lf-6.6.36-2.1.0/arch/arm/mach-imx/ele_ahab.c#L261-L278
-
https://github.com/nxp-imx/uboot-imx/blob/lf-6.6.36-2.1.0/arch/arm/mach-imx/ele_ahab.c#L297-L309
ele_auth_oem_ctnr関数とele_verify_image関数からは、ELEに対してコマンドが送信され、ELEから結果を受信します。
-
https://github.com/nxp-imx/uboot-imx/blob/lf-6.6.36-2.1.0/drivers/misc/imx_ele/ele_api.c#L76-L104
-
https://github.com/nxp-imx/uboot-imx/blob/lf-6.6.36-2.1.0/drivers/misc/imx_ele/ele_api.c#L134-L161
U-Bootの ahab_status コマンドで認証の結果を確認することができます。主要なエラーコードは以下のとおりです。
|
エラーコード |
エラーの意味 |
エラーが発生する状況 |
|---|---|---|
|
ELE_NO_AUTHENTICATION_FAILURE_IND (0xEE) |
認証は行われなかった。 |
署名していないコンテナを認証しようとした。 |
|
ELE_BAD_KEY_HASH_FAILURE_IND (0xFA) |
ヒューズSRK_HASHと、署名付きコンテナのSRK TableのHASHがが一致しない。 |
・ヒューズSRK_HASHに何も書かれていないデバイスで署名付きコンテナを認証しようとした。
・ヒューズSRK_HASH生成時に使用したSRK Tableには含まれないSRKで署名したコンテナを認証しようとした。
・署名付きコンテナのSRK Tableが書き換えられている。
・署名付きコンテナのSRK Tableが正しくロードできなかった。(メモリ上に正しく書かれていない。)
|
|
ELE_BAD_SIGNATURE_FAILURE_IND (0xF0) |
署名が正しくない。 |
・署名付きコンテナのSigned regionが書き換えられている。
・署名付きコンテナのSignatureが書き換えられている。
・上記のいずれかが正しくロードできなかった。(メモリ上に正しく書かれていない。)
|
|
ELE_BAD_HASH_FAILURE_IND (0xF1) |
ImageのHASHが、Image Arrayに書かれているHASHと異なる。 |
・署名付きコンテナのImageが書き換えられている。
・署名付きコンテナのImageが正しくロードできなかった。(メモリ上に正しく書かれていない。)
|
Note
これらのエラーコードはOEM Openの場合に観測できます。OEM Closedの場合はエラー発生時にデバイスが停止するためエラーコードは表示されません。
-
本資料はNXP製品を活用していただくための参考資料です。
-
正式な仕様は製品マニュアル・アプリケーションノートを参照ください。
-
使用ソフトウェアのバージョンなど諸条件の差異により、記載内容と実際の動作が異なる場合があります。
-
すべての機能検証を行ったものではありませんので、必ずご使用目的に適合した検証・試験を行ってください。
次回は、セキュアブート(AHAB)の実装・動作方法について、説明したいと思います。