皆さん こんにちは STM32 マイコン体験実習 セキュリティ編 パート4ですパート4ではペリフェラルと割り込む のセキュリティ設定の仕方を習得しまたトラストゾーンでアイソレーション したリソースへのアクセス方法であるセキュア呼び出しを習得します 編集3を始めます編集3ではGPIOのセキュリティ 設定とセキュア呼び出しを体験します編集3ではエクサーサイズ3プロジェクト を使いますGPIOはリセット直後に全てのピン がセキュアの設定になっていますノーマルファームウェアでGPIOを使う には該当するピンをノンセキュアの設定にします この設定はセキュア ファームウェアでしかできません緑色のLED1をセキュアGPIOに設定 して青色のLED2をノーマルGPIOに設定します どちらもノーマルファームウェア で500mmを前にトグルしますノーマルファームウェアのメイン ドットCにLED1のピンとLED2のピンをトグルするプログラムコード が書かれていますが不備がありきちんと動作しません この演習で期待 通りに動作するように手当てします 手当てが必要なフービ は2つあります一つ目はLED1に関する処理のフービ です ノーマル空間からセキュアGPIOのLED1のピンに直接アクセス しています このアクセスが不正なアクセスと見なされてハード ウェアに無視されてLED1が点滅していません 二つ目はLED2に関する 処理のフービですLED2のピンもセキュアGPIOのままになっているためノーマル ファームウェアでトグルしようとしても不正なアクセスと見なされて ハードウェアに無視されて点滅していません これから進める手当て は二段階の作業で構成されます 最初の作業でLED2ピン をノーマルGPIOに設定して青色LEDが点滅するようにします LED2ピン はGPIOのPB7なのでこのピンをノーマルGPIOに設定するにはHAR GPIO コンフィグピンアトリビュート関数にGPIOピンNセック比数を入力 してセキュアファームウェアで実行しますHAR GPIOコンフィグピンアトリビュート 関数はGPIOペリフェラルのレジスターを操作するため事前にGPIOにクロック を供給しておく必要がありますGPIOBにペリフェラルクロックを供給 するにはHAR RCC GPIOB CLKイネブル関数を実行します 以上のプログラム コードの追加をセキュアファームウェアのメインドットシーンにあるMX GPIO イニット関数に追加します このディレクトリーにあるメインドットシーンを編集します セキュアファームウェアのメインドットシーンの224行目付近にMX GPIO イニットの関数の実装コードがありますこの関数のまつびに作業1のスライド で説明したLED2ピンのPB7のセキュリティ設定を追加します このスライドは 2つ目の作業の内容をまとめていますこの演習さんではLED1ピンPC7をセキュア GPIOとして使う想定なので ノーマルファームウェアからは直接アクセスできません PC7をトグルする処理をセキュアファームウェアに実装して その処理 をノーマルファームウェアからセキュア呼び出して使えるように します セキュアファームウェアと同じソースディレクトリにあるセキュア NSC.C にこのセキュア関数の実装を追加します その後 セキュア NSC.Hヘッダーファイルにセキュア関数のインターフェース 宣言を追加します ここまでできたらノーマルファームウェアでLED1ピンを トグルしている実行行動セキュア呼び出しに変更します このディレクトリ にあるセキュア NSC.Cを編集しますセキュア NSC.Cの49行目から66行目付近 までセキュアレジスターコールバックというセキュア呼び出し 関数が既に実装されていますその直後に新しいセキュア呼び出し 関数の実装コードを追加しますセキュア呼び出し関数の定義が追加 できたら このディレクトリにあるセキュア NSC.Hヘッダーファイルに セキュア関数のインターフェース宣言を追加します 40行目付近に別のセキュア呼び出し関数のインターフェース宣言がある ので その直後にLED1をトグルするセキュア呼び出し関数の インターフェース宣言を追加します最後にノーマルファーメアにセキュア 呼び出しを実行するコードを追加します このディレクトリにある ノーマルファーメアのメイン.Cを編集します ノーマルファーメア でLED1品を直接トグルする関数を新しく追加したセキュア 呼び出し関数に置き換えますプログラムコードの追加が終わったら バッチビルドでセキュアファーメアとノーマルファーメアをビルドして マイコンにダウンロードして実行しますLED1とLED2が点滅するのを確認できたら 編集3は終了です次のページでセキュア呼び出しの 要点を説明します セキュア呼び出し関数を実装するとき 関数の戻り地の片宣言の左横に 特殊な就職紙を付ける必要があります また セキュア呼び出し関数が引数を持ちポイントを引数として 受ける場合は セキュア呼び出し関数内でそのポイントの検査をする のが差法になります この例ではバファーのポイントのサイズをCMSE チェックアドレスレンジという関数で検査し 問題なければ処理 を実行するという作りになっていますCMSE チェックアドレスレンジ関数 の振る前は次のページで説明しますCMSE チェックアドレスレンジ という関数はノーマルファーメアがどんなメモリ参照をしようと しているか検査しますノーマルファーメアから渡された バファー のポイントとサイズからアクセス対象となるメモリの範囲を把握し ノンセキュアメモリからセキュアメモリを新職する参照をしようと していることが分かった場合CMSE チェックアドレスレンジ関数 はヌルを返します チェックの結果問題なければ引数として 自分に入力されたバファーのポイントファーをそのままモドリッジとして 返しますCMSE NS ENTRYというマクロはセキュアファーメアのメイン.hヘッダーファイルで定義されていますこのマクロはセキュア呼び出し関数 を実装するときにコンパイラーによる文法の違いを吸収するよう になっています セキュア呼び出しを実装する差法を簡単に説明 しましたがより詳しく学習したいときはファーム社が出版している このアプリケーションノートが参考になります このスライドはセキュア 呼び出しの仕組みの概略図を示しています セキュアファーメア をビルドするとセキュアファーメアバイナルだけでなくインポート リーブというオブジェクトファイルも生成されます インポートリーブ はノーマルファーメアが実行するセキュア呼び出しの足がかり になる一覧表の情報を内蔵してその足がかりになる一覧表 テーブル はセキュアメモリー上にありそのテーブルがある領域のことを ノーセキュアコーラブル領域と呼びます ノーマルファーメア はセキュアメモリー領域の中でもノーセキュアコーラブル領域 にだけアクセスしてきますテーブルの中にはセキュアゲート 命令とセキュア呼び出し関数への分岐情報が並んでいます この領域 のデータは見ただけでは何のデータなのかわからないよう になっていますノーマルファーメアからノーセキュア コーラブル領域にアクセスした時まずセキュアゲート命令が実行 され ノーマルステートからセキュアステートに切り替わります セキュア ゲート命令をノーセキュアコーラブル領域で実行した場合のみセキュア ステートに切り替わりますセキュア関数を実行し その 実行を得る時 BXNS命令という特殊な分岐命令が実行されると セキュア ステートからノーマルステートに切り替わり ノーマルファーメア の呼び出し元に戻ります演習4に移ります 演習4ではセキュラブル ピリフィラルと割り込みのセキュリティ設定を体験します 演習4では エクサーサイズ4プロジェクトを使います このファーメアはタイマー 2の割り込みで青色のLED2のピンの出力を潜る仕様としています しかしタイマー2のセキュリティ設定がきちんとできておらず LED2が点滅しませんこのできていないセキュリティ 設定を訂正するという演習ですタイマー2をノーマル空間で使って タイマー2の割り込みがノーマル空間のベクターテーブルに入るようにします LED2のピンは既にノーマル空間で使えるようにしてあります 作業を始める前にセキュラブルペリフェラルをセキュア空間で使う 場合のサフォーとノーマル空間で使う場合のサフォーを説明します このフシュライドはペリフェラルをセキュア空間で使うときのサフォー をまとめていますこれから使おうとしているペリフェラル がアイスケアシーのように通信インターフェースでGPIOを使う 場合はまずGPIOをセキュアに設定します トラストドーン有効 の状態ではリセット直後からGPIOはセキュアの設定になっている ので特に何もしなくて大丈夫です明治的にGPIOをセキュアに設定する 場合はこの関数とこの引数を使います次にこれから使おうとしている ペリフェラルをセキュアに設定します ペリフェラルをセキュア に設定するにはこの関数とこの引数を使います 必要に応じてセキュア に設定したペリフェラルへの不正アクセスを検知できる ようにしますセキュアに設定したペリフェラル の割り込みを使うときは割り込みがセキュア空間のベクターテーブル に入るようにNVICを設定しますここまでできたらペリフェラル をセキュア空間で初期化しますこのスライドはペリフェラル をノーマル空間で使うときの差法をまとめています セキュリティ 設定はセキュア空間でしか設定できないため まずセキュア 空間でペリフェラルのセキュリティ設定を調整してノーマル空間 で使えるようにしますセキュリティ設定の調整が終わったら ノーマル空間でペリフェラルを初期化して使い始めるという流れになります ペリフェラルをノーマル空間で使うときに必要なセキュリティ 設定を説明しますこれから使おうとしているペリフェラル がGPIOを使う場合はGPIOをノンセキュアに設定します 次に ペリフェラルをノンセキュアに設定します 割り込みをノーマル空間 のベクターテーブルに入るようにするには NVICセットターゲット ステート関数を使いますここまでの手続きをセキュア空間 で実行してからペリフェラルの初期化はノーマル空間で 実行します 以上がセキュラブルペリフェラルをノーマル空間で 使うときの手順ですこのスライドは演習読んでの作業 内容をより細かくまとめていますまず最初にLED2ピンのPB7をノーマル 空間で使えるように設定します次にタイマー2をノーマル空間 で使えるように設定しますその後でタイマー2の割り込み がノーマル空間のベクターテーブルに入るように NVICを設定します NVICの設定についてまず最初にAの方法を試してそれができたら Bの方法を試しますLED2ピンのPB7をノーマル空間 で使えるようにする処理をセキュアファーメアのメインドとC にあるMX GPIOイニット関数に追加しますこの処理は GPIOレジスター を設定するため事前に GPIOのクロックを有効にする処理も合わせて追加 しますタイマー2ペリフェラルをノーセキュア に設定してタイマー2割り込みをノーマル空間のベクターテーブル に入るようにする設定処理をセキュアファーメアのメインドとC にあるMX GPIOイニット関数に追加します機体通りに動作するようになると青色 LEDのLED2が1秒前に点滅しますタイマー2ペリフェラルの初期化と 動作開始処理は既にノーマルファーメアに追加してあります タイマー2ペリフェラルのセキュリティ設定だけ追加します このディレクトリー にあるセキュアファーメアのメインドとCを編集します セキュアファーメア のメインドとCの150行目付近からMX GTZCイニット関数の定義が始まります ユーザーコードビギンGTZCイニット1というコメントがある 箇所にプログラムコードを追加します ここにタイマー2をノンセキュアに設定して タイマー2割り込みがノーマル空間に入るようにする 設定処理を追加しますセキュアファーメアのメインドとCの 224行目付近にMX GPIOイニット関数の定義があります ここに GPIOBペリフェラルクロックを有効にする処理とPB7をノンセキュアピン に設定する処理を追加します プログラムコードの追加が終わったらセキュアファーメア とノーマルファーメアをビルドして基盤に書き込んでLED2が点滅する か確認します 練習4の最後にパーティションヘーターファイル を変更してタイマー2割り込みがノーマル空間のベクターテーブル に入るようにする方法を試しますセキュアファーメアのメインドとCに 追加したNVICセットターゲットステート関数をコメントアウトします 次にセキュアファーメアのインクルードディレクトリーにあるパーティションヘーター ファイルを編集してタイマー2割り込みがノーマル空間のベクターテーブル に入るようにします このディレクトリーにあるパーティションヘーターファイル の427秒目にタイマー2割り込みのセキュリティ設定があります 0がセキュアで1がノー セキュアです今はタイマー2割り込みをノー セキュアにしたいので1にします実際の設定値はこのまくろになります ので変更し忘れないようにご注意ください ビッドの順序は一番下が 最上位ビッドで一番上が再開ビッドになります パーティションヘーター ファイルの変更が終わったらセキュアファーメアとノーマル ファーメアをビルドして基盤に書き込んでLED2が点滅するか確認 してください 以上で演習4は終了です このスライドはリセット 直後のSTM32エルゴマイコンの各ハードウェアのセキュリティ状態がどう なっているかを示しています内部フラッシュメモリとペリフェラル 以外はリセット直後はすべてセキュアになっています パート 4ではアームV8Mトラストゾーンセキュア呼び出しを収得し ペリフェラル割り込みのセキュリティ設定を収得しました 次のステップ でSTM32キューブMXによるトラストゾーン対応ファームやプロジェクト の作成の仕方 及びトラストゾーンの無効果の仕方を収得します ファート 5に続きますご視聴いただきましてありがとうございました