JP2009009537A - プログラム作成方法及び情報処理装置ならびにマイコン - Google Patents
プログラム作成方法及び情報処理装置ならびにマイコン Download PDFInfo
- Publication number
- JP2009009537A JP2009009537A JP2007231299A JP2007231299A JP2009009537A JP 2009009537 A JP2009009537 A JP 2009009537A JP 2007231299 A JP2007231299 A JP 2007231299A JP 2007231299 A JP2007231299 A JP 2007231299A JP 2009009537 A JP2009009537 A JP 2009009537A
- Authority
- JP
- Japan
- Prior art keywords
- instruction
- program
- processing
- language
- code
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Withdrawn
Links
Images
Abstract
【課題】高級言語でのプログラミングにおいて、耐タンパ性の高いセキュアなコードを生成するための外部仕様をサポートし、ユーザの指示があった部分については、耐タンパ性を持つ実行可能プログラムを自動的に生成するプログラム作成方法を提供する。
【解決手段】構文解析ステップと、中間語生成ステップと、レジスタ割り付けステップと、最適化処理ステップと、アセンブリ言語生成ステップと、機械語生成ステップと、機械語プログラム結合ステップとを実行し、ソースプログラム106を読み込んでから実行可能プログラム107を生成するまでの間で、ユーザの指示に基づいて、ソースプログラム106もしくは中間語109もしくはアセンブリ言語プログラム206もしくは機械語プログラム207に対して、実行可能プログラム107の動作内容の不正な解析に対抗する耐タンパ性を有するコードを自動的に生成する耐タンパコード挿入ステップを実行する。
【選択図】図2
【解決手段】構文解析ステップと、中間語生成ステップと、レジスタ割り付けステップと、最適化処理ステップと、アセンブリ言語生成ステップと、機械語生成ステップと、機械語プログラム結合ステップとを実行し、ソースプログラム106を読み込んでから実行可能プログラム107を生成するまでの間で、ユーザの指示に基づいて、ソースプログラム106もしくは中間語109もしくはアセンブリ言語プログラム206もしくは機械語プログラム207に対して、実行可能プログラム107の動作内容の不正な解析に対抗する耐タンパ性を有するコードを自動的に生成する耐タンパコード挿入ステップを実行する。
【選択図】図2
Description
本発明は、ICカード等に実装されるセキュリティ用途向けマイコンに搭載されるプログラムの作成方法に関し、特に電磁波や放射線、過電圧その他の手段により誤動作又は不正なレジスタ値もしくはメモリ値の改変を起こし、不正な動作を生じさせることによりデータの破壊や機密情報の推定を行う攻撃(誤動作解析アタック)をはじめとする動作内容の不正な推定・解析に対抗する手段を持つ、すなわち耐タンパ性を持つプログラムの作成方法、および当該プログラムを作成する情報処理装置、ならびに当該プログラムを搭載するセキュリティ用途向けマイコンに適用して有効な技術に関するものである。
ICカードは、プラスチック製カードに半導体集積回路チップを埋め込み、プログラムや機密データを密閉したカード形態の情報処理装置である。ICカードに対しては、リーダライタからのコマンドに応じてデータの転送や書き込みを行うが、取り扱うデータは、個人情報や電子マネーなど、機密性が高い情報であることが多い。そのため、第三者に対して機密情報の不正な参照を許さないために、内部の情報を勝手に書き換えることを禁止したり、暗号鍵を用いたデータの暗復号処理によって情報のやり取りを行ったり等の機能を備えている。
このような用途を持つため、ICカード用途向けマイコンにとって、内部の機密情報を不正に読み取ったり、動作内容を解析したりすることに対する耐性(耐タンパ性)は、性能指標として重要なポイントである。この耐タンパ性は、デバイスの改善だけでなく、実装するソフトウェアに対する工夫によって向上させることも可能である。
機密情報を取り扱うICカードでは、リーダライタとの間で受け渡しするデータは暗号化されている。よって、従来は、ICカード内の機密情報を解析する難易度は、暗号化アルゴリズムを解析する難易度と同じであるというように考えられてきた。しかし、ICカードの動作時の消費電流を観測することにより、ソフトウェアの動作内容が推定・解析されてしまう危険性が指摘されてきている。これは、言い換えれば「暗号化処理の実際の処理内容が解析される」危険性を示唆しているのと同じであり、「暗号化アルゴリズムが解析される」よりも容易に実現可能であるものと考えられる。
また、ICカード用途向けマイコンの動作を不正に解析する際、異常電圧・異常クロックや熱、光の照射等のストレスをマイコンに与えることにより、RAMやレジスタの内容を不正な状態にし、プログラムの命令コードを不正に変化させ、強引に本来のプログラムフローとは異なる不正経路の動作を生じさせることにより、ソフトウェアの動作内容を推定・解析する手法(誤動作解析アタック)がある。
さらに、この誤動作解析アタックにより、チップに計算誤りを起こさせ、正しい計算結果と誤った計算結果の差分を用いて暗号鍵情報を推定するアタック手法も開発されている。このアタック手法の特徴は、アタックに必要な時間が非常に少ない点である。例えば、CRT演算法を用いたRSA暗号に対する誤動作解析アタック手法では、鍵長にかかわらず、たった1回の演算誤りが得られれば、正しい値と誤った値の差分と公開鍵のモジュロNとの最大公約数から、秘密素数が得られ、その結果から秘密鍵を推定できることが知られている。
秘密鍵暗号系として広く用いられているDES暗号では、正しい演算結果と誤った演算結果が数個から数十個得られると、秘密鍵を得ることができることがE.Bihamらによって報告されている。DES暗号の後継暗号として提案されたAES暗号でも途中の演算のうちの1バイトに誤計算を起こさせることができれば、2回の誤計算結果から鍵を得ることができる手法がJ.J.Quisquaterらによって提案されている。これらのアタックは、アタックに必要な計算量が暗号鍵の長さにかかわらず一定か、もしくは暗号鍵のビット長のみに比例し、かつ計算量は非常に小さいという特徴がある。
暗号鍵を推定する誤動作解析アタック対策としては、暗号に応じて(1)処理を二重化することにより2回計算を行い、2回の演算結果が等しくなることを確認する方法、(2)逆計算による検算を行う方法、(3)剰余体上での縮退表現や、パリティを用いた演算の整合性のチェックなどが提案されている。
このような不正な動作解析手法に対抗するため、ソフトウェアに対する工夫によって耐タンパ性を向上させようとした場合、従来のソフトウェア開発ツールでは、特開2002−334317号公報(特許文献1)に提示されているように、ユーザ自身が手作業により耐タンパ性を向上させるセキュアなプログラムを記述する必要があった。しかし、ユーザがプログラムで記述できる部分は限定的であり、また、開発ツールが生成する機械語を完全にコントロールすることも難しいため、実際にセキュアなプログラムを手作業により作成することは難しい。
一方、コンパイラやソフトウェア実装方式の工夫、特にプログラム中で用いるデータ領域の工夫をすることで攻撃者からの攻撃を回避する方法としては、特開2001−202237号公報(特許文献2)に提示されているように、実行可能なバイナリデータ中にダミーデータの埋め込み場所を設定する方法や、特開2003−330563号公報(特許文献3)に提示されているように、スタック構造をプログラム毎に変更することでプログラム破壊攻撃に対する耐性を向上する方法といった技術が提案されている。
なお、以下では、ユーザが記述したソースプログラムを入力として、機械語で記述された最終的な実行可能プログラムを生成する開発ツール全般(コンパイラやリンケージエディタなどを含む)を言語ツールと呼称する。
特開2002−334317号公報
特開2001−202237号公報
特開2003−330563号公報
前述した通り、ユーザが耐タンパ性を持つプログラムを作成することは難しい。その理由は、昨今ではプログラムがC言語などの高級言語で開発されることが多く、アセンブリ言語のソースプログラムをユーザが直接作成するというのが現実的ではないことなどが挙げられる。また、耐タンパ性を持つプログラムを手作業で開発すること自体、通常のソフトウェア開発と比較して多くの工数を必要とすることも挙げられる。
仮にC言語のような高級言語で耐タンパ性を持つソースプログラムを記述したとしても、動作内容を変えずに実行性能を上げたり、実行可能プログラムのサイズを削減したりする言語ツールの最適化処理において、前記記述が冗長な命令として削除される可能性がある。あるいは、耐タンパ性を高めるのに直接関係無い冗長な命令まで生成される可能性がある。高級言語による記述では、実際の命令列まで細かく制御するのは一般に困難である。また、仮にユーザが耐タンパ性を持つプログラムを作成したとしても、その効果を検証するには実際に不正な動作解析による攻撃を行ってみる必要があり、実現は難しい。
また、ユーザがどのように耐タンパ性を持つプログラムを作成すればよいのかについて必ずしも精通していない点も挙げられる。耐タンパ性を持つプログラムを作成するには、耐タンパ性を向上させるための種々のプログラミング技法に加えて、対象マシンの機械語命令の仕様や特性を知らなければならないが、高級言語でプログラミングしている場合、これは一般的には望めないことである。
そこで本発明の目的は、C言語などの高級言語でのプログラミングにおいて、耐タンパ性の高いセキュアなコードを生成するための外部仕様(オプションもしくは拡張言語仕様など)を言語ツールでサポートし、ソースプログラムの中で前記インタフェースによりユーザの指示があった部分については、耐タンパ性を持つセキュアな実行可能プログラムを自動的に生成するプログラム作成方法を提供することにある。
本発明の前記ならびにその他の目的と新規な特徴は、本明細書の記述および添付図面から明らかになるであろう。
本願において開示される発明のうち、代表的なものの概要を簡単に説明すれば、次のとおりである。
本発明は、コンピュータにより、プログラミング言語で記述されたソースプログラムを読み込んで実行可能プログラムを生成するプログラム作成方法であって、前記コンピュータは、前記ソースプログラムを読み込んで構文解析を行う構文解析ステップと、該ソースプログラムから中間語の生成を行う中間語生成ステップと、該中間語に対してレジスタを割り付けるレジスタ割り付けステップと、該中間語に対して最適化処理を行う最適化処理ステップと、該中間語からアセンブリ言語プログラムを生成するアセンブリ言語生成ステップと、該アセンブリ言語プログラムから機械語プログラムを生成する機械語生成ステップと、該機械語プログラムと他の機械語プログラムとを結合させて実行可能プログラムを生成する機械語プログラム結合ステップとを実行し、前記ソースプログラムを読み込んでから前記実行可能プログラムを生成するまでの間で、ユーザの指示に基づいて、前記ソースプログラムもしくは前記中間語もしくは前記アセンブリ言語プログラムもしくは前記機械語プログラムに対して、前記実行可能プログラムの動作内容の不正な解析に対抗する耐タンパ性を有するコードを自動的に生成する耐タンパコード挿入ステップを実行することを特徴とするものである。
また、本発明は、前記プログラム作成方法を実行する情報処理装置および前記プログラム作成方法により生成された実行可能プログラムを格納するマイコンにも適用することができる。
本願において開示される発明のうち、代表的なものによって得られる効果を簡単に説明すれば以下のとおりである。
本発明によれば、ユーザが手作業で作るのが難しい耐タンパ性を持つセキュアな実行可能プログラムを、言語ツールで自動的に生成することができる。これによりセキュアなプログラムの開発生産性が向上する。
以下、本発明の実施の形態を図面に基づいて詳細に説明する。なお、実施の形態を説明するための全図において、同一部には原則として同一の符号を付し、その繰り返しの説明は省略する。
<概要>
以下、本発明の実施の形態である言語ツールについて説明する。本実施の形態での言語ツールは、耐タンパ性を有する機械語を生成するための外部仕様(拡張言語仕様もしくはオプションなど)を有し、容易に耐タンパ性を有するプログラムを生成することが出来るインタフェースを提供する。
以下、本発明の実施の形態である言語ツールについて説明する。本実施の形態での言語ツールは、耐タンパ性を有する機械語を生成するための外部仕様(拡張言語仕様もしくはオプションなど)を有し、容易に耐タンパ性を有するプログラムを生成することが出来るインタフェースを提供する。
本実施の形態での言語ツールは、ソースプログラムにおいて前記インタフェースによってユーザにより指示された部分に対して、その動作内容を変えずに耐タンパ性を向上させる機械語を生成するための耐タンパコード挿入ステップを実行する。この耐タンパコード挿入ステップにて生成される、耐タンパ性を向上させるコードは以下の6種類である。
(1)多重条件分岐の分岐経路検証
誤動作解析アタックにより、条件分岐用の情報レジスタの内容などが不正になる場合、不正な経路の実行となる危険がある。条件分岐がネストしているような多重条件分岐の場合、各条件分岐での判定処理を正しく通過したかどうかをチェックするための情報をレジスタやメモリ上に保持し、各条件分岐先の処理のブロック内で前記情報が妥当な値かどうかをチェックすることで不正な分岐経路の実行を防ぐ。
誤動作解析アタックにより、条件分岐用の情報レジスタの内容などが不正になる場合、不正な経路の実行となる危険がある。条件分岐がネストしているような多重条件分岐の場合、各条件分岐での判定処理を正しく通過したかどうかをチェックするための情報をレジスタやメモリ上に保持し、各条件分岐先の処理のブロック内で前記情報が妥当な値かどうかをチェックすることで不正な分岐経路の実行を防ぐ。
(2)条件分岐判定の多重化
誤動作解析アタックにより、条件分岐用の情報レジスタの内容などが不正になる場合、不正な経路の実行となる危険がある。よって、条件分岐での判定処理を単一ではなく、二重三重に実施することにより、正常な経路への分岐をより確実に行い、不正な分岐経路実行の危険を抑える。
誤動作解析アタックにより、条件分岐用の情報レジスタの内容などが不正になる場合、不正な経路の実行となる危険がある。よって、条件分岐での判定処理を単一ではなく、二重三重に実施することにより、正常な経路への分岐をより確実に行い、不正な分岐経路実行の危険を抑える。
(3)関数呼び出し時のパラメータ内容チェック
誤動作解析アタックにより、RAM(実行時スタック)が不正な状態となった場合、関数呼び出しのパラメータ(引数)が不正になり、不正な動作を生じさせる危険がある。よって、関数呼び出し時に、呼び出し側でパラメータの合計値(チェックサム)等をメモリ又はレジスタ上に設定し、呼び出された側では受け取ったパラメータの合計値を計算し、呼び出し側で設定した合計値と比較して関数呼び出し間のパラメータの妥当性チェックを行うことにより、不正な関数の実行を防ぐ。
誤動作解析アタックにより、RAM(実行時スタック)が不正な状態となった場合、関数呼び出しのパラメータ(引数)が不正になり、不正な動作を生じさせる危険がある。よって、関数呼び出し時に、呼び出し側でパラメータの合計値(チェックサム)等をメモリ又はレジスタ上に設定し、呼び出された側では受け取ったパラメータの合計値を計算し、呼び出し側で設定した合計値と比較して関数呼び出し間のパラメータの妥当性チェックを行うことにより、不正な関数の実行を防ぐ。
(4)実行時の電流特性希薄化
プログラムの動作内容を変えずに、実行時の電流特性の特徴を薄めるような機械語を生成する。これにより、本実施の形態での言語ツールによって生成されたプログラムの動作内容を消費電流から解析することは困難となり、ICカード等に保持する機密情報を知られる危険性を抑えることができる。実行時の電流特性の特徴を薄める手法としては、(a)ループ処理についての複数パターンのコード生成による電流特性複雑化、(b)条件分岐の各分岐経路の実行時間を均一化することによる電流特性近似化、の2通りがある。
プログラムの動作内容を変えずに、実行時の電流特性の特徴を薄めるような機械語を生成する。これにより、本実施の形態での言語ツールによって生成されたプログラムの動作内容を消費電流から解析することは困難となり、ICカード等に保持する機密情報を知られる危険性を抑えることができる。実行時の電流特性の特徴を薄める手法としては、(a)ループ処理についての複数パターンのコード生成による電流特性複雑化、(b)条件分岐の各分岐経路の実行時間を均一化することによる電流特性近似化、の2通りがある。
(5)チェックサム算出および検証
命令コードを積算したチェックサムの期待値を算出し、実行時の命令コードの積算値と比較することでプログラムフローの正常実行を監視することを可能とする機械語を生成する。これにより、本実施の形態での言語ツールによって生成されたプログラムを、不正な動作を起こさせる誤動作解析アタックにより解析することは困難となり、ICカード等に保持する機密情報を知られる危険性を抑えることができる。
命令コードを積算したチェックサムの期待値を算出し、実行時の命令コードの積算値と比較することでプログラムフローの正常実行を監視することを可能とする機械語を生成する。これにより、本実施の形態での言語ツールによって生成されたプログラムを、不正な動作を起こさせる誤動作解析アタックにより解析することは困難となり、ICカード等に保持する機密情報を知られる危険性を抑えることができる。
(6)プログラムコードの二重化処理
誤動作解析アタック対策として、二重化処理を用いることでプログラムの動作誤りを検出する方法で、特にプログラムの動作系を二重化するハードウェアの構成を用いず、既存の単一処理系を前提としたハードウェア上で実現する方法として、プログラムコードを二重化することにより2回演算を行い、2回の演算結果が等しくなることを確認することにより、プログラムの動作誤りを検出する。
誤動作解析アタック対策として、二重化処理を用いることでプログラムの動作誤りを検出する方法で、特にプログラムの動作系を二重化するハードウェアの構成を用いず、既存の単一処理系を前提としたハードウェア上で実現する方法として、プログラムコードを二重化することにより2回演算を行い、2回の演算結果が等しくなることを確認することにより、プログラムの動作誤りを検出する。
以下、これら6種類の手法を適用した言語ツールの例について説明する。
<実施の形態1>
以下、本発明の実施の形態1として、多重条件分岐の分岐経路検証を行う実行可能プログラムを生成する言語ツールの例について説明する。
以下、本発明の実施の形態1として、多重条件分岐の分岐経路検証を行う実行可能プログラムを生成する言語ツールの例について説明する。
図1は、本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図である。図1に示すように、情報処理装置はCPU101、ディスプレイ102、入出力デバイス103、主記憶装置104、及び外部記憶装置105より構成されている。主記憶装置104には、本実施の形態での言語ツール108と、言語ツール108によるコンパイル処理過程で生成される中間語109とが保持される。外部記憶装置105には、言語ツール108への入力となるソースプログラム106と、言語ツール108により生成される実行可能プログラム107とが保持される。コンパイル処理はCPU101が言語ツール108を実行することにより行われる。ディスプレイ102はコンパイル処理状況等を表示することによりユーザに通知する。入出力デバイス103はユーザからのコマンドを言語ツール108に与えるために用いる。
以下に、本実施の形態での言語ツールの具体的な内容について説明する。図2は、本実施の形態での言語ツールの構成と処理概要の例を表した図である。図2において、言語ツール108はコンパイラ201、アセンブラ204、リンケージエディタ205から構成され、コンパイラ201はフロントエンド202とバックエンド203とに分けられる。
言語ツール108は図1に示す情報処理装置上で稼動し、まずコンパイラ201がC言語などの高級言語で記述されたソースプログラム106を読み込む。コンパイラ201は、読み込んだソースプログラム106に対して、フロントエンド202によって構文解析、字句解析、意味解析の処理を行い、中間語109を生成する。中間語109は、コンパイル処理過程で必要となるコンパイラ内部データである。
次に、コンパイラ201は、バックエンド203によって、耐タンパコード挿入処理を行い、中間語109に対して耐タンパ性を向上させるセキュアな命令列を追加・生成する。その後、中間語109を基にレジスタ割り付け処理、最適化処理を行って、アセンブリ言語プログラム206を生成する。これにより、耐タンパ性を向上させるセキュアな命令列を含んだ形でアセンブリ言語プログラム206が生成される。
その後、コンパイラ201によって生成されたアセンブリ言語プログラム206をアセンブラ204が読み込み、機械語プログラム207を生成する。その後、リンケージエディタ205が機械語プログラム207に対して他の機械語プログラムを結合(リンク)することによって、実行可能プログラム107が生成される。言語ツール108によってこのように作成された実行可能プログラム107は、ICカードなどのターゲットマイコン208に格納され実行される。
なお、耐タンパコード挿入処理は、本実施の形態での言語ツール108では中間語生成処理の後に中間語109に対して行っているが、中間語109に対して行う場合は、アセンブリ言語生成処理の前で行われればよく、最適化処理の後に行うことも可能である。また、中間語109に対してではなくアセンブリ言語プログラム206や、機械語プログラム207に対してアセンブラ204やリンケージエディタ205が耐タンパコード挿入処理を行うことも可能である。さらに、可能な場合には、図示しないプリプロセッサ等によりソースプログラム106に対して耐タンパコード挿入処理を行い、その後コンパイラ201による処理を行うようにすることもできる。
図3は、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図である。ターゲットマイコン208は、特に制限されないが、公知の半導体集積回路製造技術により、単結晶シリコン基板などの一つの半導体基板に形成される主にICカード用途向けマイコンであり、不揮発性メモリ301、揮発性メモリ304、入出力部305、コプロセッサ306、CPU307、暗号専用回路308、およびこれらを接続するバス309により構成される。
不揮発性メモリ301は、特に制限されないが、フラッシュメモリなどで構成され、不揮発性メモリ301内のプログラム格納領域302には、言語ツール108が生成した実行可能プログラム107が格納される。この実行可能プログラム107は、CPU307によって実行される。また、データ格納領域303には、暗号鍵データや機密情報などのデータが格納される。
揮発性メモリ304は、CPU307での演算処理における変数記憶領域や、中間データの格納領域として利用される。暗号専用回路308では、ターゲットマイコン208が搭載されたICカード310の不正使用を回避するための暗号処理が行われる。
ここで、例えばプログラム格納領域302には、耐タンパコード挿入処理によって追加・生成されたセキュアな命令列を含んだ実行可能プログラム107以外にも、必要であれば耐タンパコード挿入処理を無効にすることにより生成された、セキュアな命令列が含まれない第2の実行可能プログラム107が格納されていてもよい。
この耐タンパコード挿入処理の有効・無効については、ソースプログラム106を言語ツール108に読み込む際に、任意のレジスタに設定することによってその制御を行うことが可能である。これによって、耐タンパ性が必要とされるプログラムに対しては耐タンパコード挿入処理を行うことで耐タンパ性を高め、それ以外のプログラムに対しては、プログラム容量を抑えた実行可能プログラム107を生成することができ、不要なプログラム容量の増大を抑制することが可能となる。
また、実行可能プログラム107を、外部端子311を介してICカード310の外部から揮発性メモリ304にロードし、CPU307により実行する構成とすることも可能である。揮発性メモリ304は、ダイナミック・ランダム・アクセス・メモリ(DRAM)や、スタティク・ランダム・アクセス・メモリ(SRAM)とすることができる。かかる構成においても、前述した実行可能プログラム107を不揮発性メモリ301に格納する構成の場合と同様の作用効果を得ることができる。
図4は、本実施の形態でのコンパイラ201での処理の流れの例を示したフローチャートである。まずステップ401で、フロントエンド202にてソースプログラム106を読み込んで構文解析を行う。構文解析処理については、例えば「エイホ、セシィ、ウルマン著:コンパイラI(サイエンス社、1990年)30頁〜74頁」などに記載されているので、ここでは詳しく説明しない。次に、ステップ402でフロントエンド202にて中間語生成を行う。中間語については同じく「エイホ、セシィ、ウルマン著:コンパイラII(サイエンス社、1990年)564頁〜617頁」などに記載されているので、ここでは詳しく説明しない。
次に、ステップ403で未処理の関数があるかどうかを調べる。C言語では入力ソースプログラムは関数という処理単位に分かれているので、本実施の形態での言語ツール108では関数ごとに翻訳処理を行うものとする。未処理の関数がなければここで終了する。未処理の関数があれば、ステップ404で未処理の関数を取り出し、該関数が耐タンパコード挿入対象の関数かどうかを調べる。耐タンパコード挿入対象の関数かどうかは、例えば中間語109内の各入力関数に対して作られるテーブルに情報(ON/OFF)を記録しておき、該情報を参照することによって行う。該情報はステップ401の構文解析時に、ソースプログラム106中で後述する言語仕様拡張により耐タンパコード挿入の指示がされた関数に対して設定されるものとする。
前記関数が耐タンパコード挿入対象である場合はステップ405へ進み、バックエンド203にて中間語109に対して耐タンパコード挿入の処理を行った後ステップ406へ進む。ステップ405の耐タンパコード挿入処理の詳細については後述する。耐タンパコード挿入対象の関数ではない場合はステップ406へ進む。なお、前述のように、ステップ405の耐タンパコード挿入処理は、ステップ407の最適化処理の後で行うことも可能である。
ステップ406では、バックエンド203にて中間語109に対してレジスタ割り付けを行う。レジスタ割り付け処理については同じく「エイホ、セシィ、ウルマン著:コンパイラII(サイエンス社、1990年)659頁〜665頁」などに記載されているので、ここでは詳しく説明しない。次にステップ407へ進み、バックエンド203にて中間語109に対して最適化処理を行う。最適化処理については同じく「エイホ、セシィ、ウルマン著:コンパイラII(サイエンス社、1990年)715頁〜881頁」などに記載されているので、ここでは詳しく説明しない。
次にステップ408へ進み、バックエンド203にて中間語109からアセンブリ言語の生成を行い、アセンブリ言語プログラム206を出力する。アセンブリ言語生成処理については同じく「エイホ、セシィ、ウルマン著:コンパイラII(サイエンス社、1990年)679頁〜692頁」などに記載されているので、ここでは詳しく説明しない。
図5は、本実施の形態でのコンパイラ201への入力となる、ソースプログラム106の例である。本実施の形態ではソースプログラム106はC言語で記述されたものを対象としており、耐タンパコード挿入対象を指定するための言語仕様拡張がされている。行501に示す「#pragma secure_func(f,g)」がそれであり、行502の関数fと行512の関数gに対して耐タンパコードを挿入することを指示している。指示がされていない行516の関数hに対しては通常のコード生成を行う。行502の関数fは、行504の条件式cond1の値が真の場合は行505の実行文1を実行し、偽の場合は、行506の条件式cond2の値が真の場合は行507の実行文2を、偽の場合は行509の実行文3を実行することを示している。
図6は、本実施の形態でのコンパイラ201により生成される、ステップ405での耐タンパコード挿入処理を行う前の、中間語109の例を示したものである。コンパイラが生成する中間語には、一般にソースプログラムに近いレベルのものから、機械語に近いレベルのものまで存在するが、本実施の形態では機械語に近いレベルのものを想定している。中間語109は命令と呼ばれるメモリセルを2重リンクでリスト状に繋げる形で構成しており、図中の実線の矢印は命令間のリンクを表している。
図6に示す中間語109は、図5のソースプログラム106の行504〜行510の部分に相当するものである。命令601(cmp)は、定数0(偽)と変数cond1とを比較(compare)することを示す。命令602(beq)は、前記比較の結果、0とcond1が等しい(Equal)場合に、オペランドのポインタで指される(リンクされる)命令605へ分岐することを示す。そうではない(等しくない)場合は、直後の命令603に制御を移す(fall-through)。命令603は、図5のソースプログラム106における行505の実行文1に対応する文である。ここでは1つの命令で表されているが、複数の命令から構成されている場合もある。命令604(bra)は、オペランドのポインタで指される命令610へ無条件分岐することを示す。
命令605(cmp)は、定数0(偽)と変数cond2とを比較(compare)することを示す。命令606(beq)は、前記比較の結果、0とcond2が等しい(Equal)場合に、オペランドのポインタで指される(リンクされる)命令609へ分岐することを示す。そうではない(等しくない)場合は、直後の命令607に制御を移す(fall-through)。命令607は図5のソースプログラム106における行507の実行文2に対応する文である。ここでは1つの命令で表されているが、複数の命令から構成されている場合もある。命令608(bra)は、オペランドのポインタで指される命令610へ無条件分岐することを示す。
命令609は、図5のソースプログラム106における行509の実行文3に対応する文である。ここでは1つの命令で表されているが、複数の命令から構成されている場合もある。命令610は、図5のソースプログラム106におけるif...else if...else 節終了後に後続で実行される命令である。
図7は、本実施の形態での、図4のステップ405での耐タンパコード挿入処理の詳細な例を表すフローチャートである。まずステップ701で、中間語109内の全命令の処理済フラグをOFFにする。次にステップ702において、中間語109内の最初の命令を取り出し、それをtとする。次にステップ703で、tがNULLかどうかを調べる。NULLであれば命令がすべて処理済みなので終了する。NULLでなければステップ704へ進み、tが条件分岐命令かどうかを調べる。条件分岐命令でなければステップ708へ進み、tの次の命令を新たにtとし、ステップ703から繰り返す。ステップ704でtが条件分岐命令であれば、ステップ705でtの処理済フラグがONかどうかを調べる。ONであればステップ708へ進み、ONでなければステップ706へ進む。
ステップ706では、tが多重条件分岐の開始命令かどうかを調べる。tが多重条件分岐の開始命令であるか否かは、(1)tの直前の命令が比較命令であること、(2)tの分岐先命令から始まる、合流や分岐のない命令列(基本ブロック)の末尾が、比較命令とその直後の条件分岐命令であること、の2つを判断することによっておこなう。分岐先にさらに比較命令、条件分岐命令のパターンが連続している場合は、連続している限り同じ多重条件分岐に属するとみなす。前記判断により、tが多重条件分岐の開始命令でなければ、ステップ708へ進む。tが多重条件分岐の開始命令であれば、ステップ707へ進む。
ステップ707では、以下の(1)〜(5)の処理を行う。
(1)多重条件分岐の各比較命令をそれぞれc_0、c_1、...、c_nとする。
(2)c_0の直前に経路情報の初期化命令を挿入する。
(3)c_iの直後に経路情報の設定命令を挿入する。
(4)多重条件分岐の各分岐先に経路情報のチェック命令を挿入する。
(5)多重条件分岐の経路中の各条件分岐命令、及び前記(4)で挿入したチェック命令中の条件分岐命令の処理済フラグをONにする。
前記(1)〜(5)の処理終了後、ステップ708へ進む。
(1)多重条件分岐の各比較命令をそれぞれc_0、c_1、...、c_nとする。
(2)c_0の直前に経路情報の初期化命令を挿入する。
(3)c_iの直後に経路情報の設定命令を挿入する。
(4)多重条件分岐の各分岐先に経路情報のチェック命令を挿入する。
(5)多重条件分岐の経路中の各条件分岐命令、及び前記(4)で挿入したチェック命令中の条件分岐命令の処理済フラグをONにする。
前記(1)〜(5)の処理終了後、ステップ708へ進む。
図8は、図6の中間語109に対して、図7に示す耐タンパコード挿入処理を行った後の中間語109の例を示すものである。以下に、図7の処理フローに従って該中間語109が生成される過程を示す。
ステップ702で、図6の中間語109から最初の命令(命令601)を取り出し、それをtとする。ステップ703でtがNULLかどうかを調べる。tはNULLではないのでステップ704へ進み、tが条件分岐命令かどうかを調べる。tは条件分岐命令ではないのでステップ708へ進み、tの次の命令(命令602)を新たにtとする。再びステップ703でtがNULLかどうかを調べ、NULLではないのでステップ704へ進み、tが条件分岐命令かどうかを調べる。tは条件分岐命令なのでステップ705へ進み、処理済フラグがONかどうかを調べる。処理済フラグはOFFなのでステップ706へ進み、多重条件分岐の開始命令かどうかを調べる。(1)tの直前の命令(命令601)は比較命令であり、(2)tの分岐先命令(命令605)が比較命令であり、その直後の命令(命令606)が条件分岐命令なので、tは多重条件分岐の開始命令であると判定され、ステップ707へ進む。
ステップ707では、以下の(1)〜(5)の処理を行う。
(1)多重条件分岐の各比較命令(命令601、命令605)をそれぞれc_0、c_1とする。
(2)c_0の直前に経路情報の初期化命令(命令801)を挿入する。命令801(mov)は定数0を変数flagに移動(Move)することを意味する。
(3)c_0、c_1の直後にそれぞれ、c_0、c_1を通ったことを変数flagに記録する経路情報の設定命令(命令802、命令803)を挿入する。命令802、命令803(bset/eq)は、c_0、c_1の比較結果が等しい(Equal)場合に、それぞれ変数flagの0番目、1番目のビットに1を設定する(Set)することを意味する。
(4)多重条件分岐の各分岐先の処理にそれぞれ、変数flagの0番目のビットに1が設定されている(変数flagの値が1である)かどうか、及び0番目と1番目のビットに1が設定されている(変数flagの値が3である)かどうかを定数と比較して調べる命令(命令804、命令807)と、比較結果が等しければ正常処理へと分岐する条件分岐命令(命令805、命令808)と、エラー処理へ無条件に分岐する分岐命令(命令806、命令809)とを挿入する。命令805、命令808(beq)はそれぞれ、命令804、命令807の比較結果が等しい(Equal)場合に、オペランドのポインタで指される(リンクされる)命令607、命令609へ分岐することを示す。
(5)多重条件分岐の経路中の各条件分岐命令(命令602、命令606)、及び前記(4)で挿入した各条件分岐命令(命令805、命令808)の処理済フラグをONにする。
(1)多重条件分岐の各比較命令(命令601、命令605)をそれぞれc_0、c_1とする。
(2)c_0の直前に経路情報の初期化命令(命令801)を挿入する。命令801(mov)は定数0を変数flagに移動(Move)することを意味する。
(3)c_0、c_1の直後にそれぞれ、c_0、c_1を通ったことを変数flagに記録する経路情報の設定命令(命令802、命令803)を挿入する。命令802、命令803(bset/eq)は、c_0、c_1の比較結果が等しい(Equal)場合に、それぞれ変数flagの0番目、1番目のビットに1を設定する(Set)することを意味する。
(4)多重条件分岐の各分岐先の処理にそれぞれ、変数flagの0番目のビットに1が設定されている(変数flagの値が1である)かどうか、及び0番目と1番目のビットに1が設定されている(変数flagの値が3である)かどうかを定数と比較して調べる命令(命令804、命令807)と、比較結果が等しければ正常処理へと分岐する条件分岐命令(命令805、命令808)と、エラー処理へ無条件に分岐する分岐命令(命令806、命令809)とを挿入する。命令805、命令808(beq)はそれぞれ、命令804、命令807の比較結果が等しい(Equal)場合に、オペランドのポインタで指される(リンクされる)命令607、命令609へ分岐することを示す。
(5)多重条件分岐の経路中の各条件分岐命令(命令602、命令606)、及び前記(4)で挿入した各条件分岐命令(命令805、命令808)の処理済フラグをONにする。
次にステップ708へ進み、tの次の命令(命令603)を新たにtとし、ステップ703へ戻る。ステップ703で再びtがNULLかどうかを調べ、NULLではないのでステップ704へ進み、tが条件分岐命令かどうかを調べる。tは条件分岐命令ではないので、ステップ708へ進み、tの次の命令(命令604)を新たにtとする。この時点で、当該処理中の中間語109に条件分岐命令であって処理済フラグがOFFの命令は存在しないため、以降の処理ではステップ707に入ることはなく、耐タンパコードの挿入処理は行われない。
図9は、図5のソースプログラム106を入力としたときの、従来技術のコンパイラの出力するアセンブリ言語プログラムの例である。まず「cmp #0,cond1」命令(命令901)により、定数0(偽)の値とcond1の値を比較し、その結果を条件コードレジスタに格納する。次の「beq L1」命令(命令902)では、該条件コードレジスタの値を調べ、比較結果が等しい(Equal)場合はラベルL1(命令905)へ分岐する。そうではない(等しくない)場合は直後の命令へ制御が移り、実行文1(命令903)を実行して、「bra L2」命令(命令904)でラベルL2(命令912)へ分岐する。
命令902でL1へ分岐した場合、「cmp #0,cond2」命令(命令906)により、定数0(偽)の値と条件式cond2の値を比較し、その結果を条件コードレジスタに格納する。次の条件分岐命令(命令907)では、該条件コードレジスタの値を調べ、比較結果が等しい場合はラベルL3(命令910)へ分岐する。そうではない(等しくない)場合は直後の命令へ制御が移り、実行文2(命令908)を実行して、命令909でL2へ分岐する。命令907でL3へ分岐した場合、実行文3(命令911)を実行して直後の命令(分岐先L2と同じになる)へ制御を移す。
図10は、図5のソースプログラム106を入力としたときの、本実施の形態でのコンパイラ201が出力するアセンブリ言語プログラム206の例である。まず、「mov #0,R1」命令(命令1001)でレジスタR1を0に初期化する。次に、図5のソースプログラム106の行504のif文に対応する条件比較命令(命令1002)の直後で、「bset/eq #0,R1」命令(命令1003)により、前記条件比較命令の比較結果が等しい場合にレジスタR1の0番ビットに1を立てることにより、前記if文を通ってきたことを記録し、次の条件分岐命令1004でラベルL1(命令1007)へ分岐する。そうではない(等しくない)場合は、実行文1(命令1005)を実行した後、分岐命令(命令1006)でラベルL2(命令1023)へ分岐し、多重条件分岐を抜ける。
命令1004でL1へ分岐した場合、図5のソースプログラム106の行506のif文に対応する条件比較命令(命令1008)の直後で、該条件比較命令の比較結果が等しい場合にレジスタR1の1番ビットに1を立てることにより(命令1009)、前記if文を通ってきたことを記録する。
命令1008の条件比較命令の比較結果が等しくない場合は、命令1010の条件分岐命令で分岐せずに命令1011の条件比較命令へ進み、レジスタR1の0番ビットに1が設定されている(R1の値が1である)かどうかを調べることにより、図5のソースプログラム106の行504のif文を通ってきたかどうかをチェックする。前記条件比較命令の比較結果が等しい(Equal)場合、次の「beq L4」命令(命令1012)の条件分岐によりラベルL4(命令1014)に分岐し、実行文2(命令1015)を実行した後、分岐命令(命令1016)により多重条件分岐を抜ける。命令1011の条件比較命令の比較結果が等しくない場合、条件分岐命令(命令1012)で分岐せず、次の分岐命令(命令1013)でエラー処理(error())へ分岐する。
命令1008の条件比較命令の比較結果が等しい場合は、命令1010の条件分岐命令でラベルL3(命令1017)へ分岐して、命令1018の条件比較命令へ進み、レジスタR1の0番ビットと1番ビットに1が設定されている(R1の値が3である)かどうかを調べることにより、図5のソースプログラム106の行504及び行506のif文を通ってきたかどうかをチェックする。前記条件比較命令の比較結果が等しい場合、次の条件分岐命令(命令1019)によりラベルL5(命令1021)に分岐し、実行文3(命令1022)を実行した後、多重条件分岐を抜ける。命令1018の条件比較命令の比較結果が等しくない場合、条件分岐命令(命令1019)で分岐せず、次の分岐命令(命令1020)でエラー処理(error())へ分岐する。このように、実行可能プログラム107の実行の途中で正しい経路を通っていないと判定された場合、エラー処理へと制御が移るため、誤動作の可能性が低くなる。
本実施の形態では、図5において、耐タンパコードを挿入する関数をソースプログラム106中で#pragma指示文により指定していたが、これに限定されるものではなく、コンパイラ起動コマンドに付加するコンパイルオプションによって指定することもできる。図11はその例である。ここで「cc」はコンパイルコマンド、「prog.c」はコンパイル対象ファイル(ソースプログラム)、「-secure_func=f,g」は耐タンパコード挿入を行う対象の関数として関数fと関数gを指定していることを表している。すなわち、図11のコンパイルコマンドにより、ソースプログラムprog.c中の関数fと関数gについては耐タンパコード挿入を行い、それ以外の関数については通常通り耐タンパコード挿入を行わずにアセンブリ言語プログラム206を生成することを指示している。
また、本実施の形態では、図5において、耐タンパコードを挿入するかどうかを関数ごとに指定していたが、さらに細かい粒度(たとえばソースプログラム106の文単位)で指定することも可能である。図12はそのような指定の例を示したものである。図12において、関数内の「#pragma secure_stm」(命令1204)と「#pragma secure_stm_end」(命令1212)で囲まれた範囲の文に対して耐タンパコード挿入を行うことを指示する。このようにした場合、コンパイラ201による中間語109の生成において、耐タンパコード挿入対象かどうかを示すフラグを中間語109内の関数ごとではなく命令ごとに設定することで、命令ごとに耐タンパコード挿入の制御が可能になる。
なお、図4のステップ407の最適化処理では、耐タンパコード挿入処理の処理済フラグがONになっている中間語109の命令については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、多重条件分岐の分岐経路検証といった、ユーザが手作業で作成するのが難しい耐タンパ性を持つ実行可能プログラム107を自動的に生成することができ、耐タンパ性を持つアプリケーションの開発生産性が向上する。
<実施の形態2>
以下、本発明の実施の形態2として、条件分岐判定を多重化した実行可能プログラムを生成する言語ツールの例について説明する。
以下、本発明の実施の形態2として、条件分岐判定を多重化した実行可能プログラムを生成する言語ツールの例について説明する。
本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。また、本実施の形態での言語ツール108の構成と処理概要の例は図2と同じである。また、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。図4のステップ405の耐タンパコード挿入処理の詳細は、実施の形態1でのものとは異なるため、図13〜図16を用いてさらに詳しく説明する。
図13は、本実施の形態での言語ツール108への入力となる、ソースプログラム106の例である。行1301において変数aと変数bの値を比較し、一致している場合は行1302の実行文1を、そうではない場合は行1304の実行文2を行うことを示している。
図14は、本実施の形態での言語ツール108により生成される、図4のステップ405での耐タンパコード挿入処理を行う前の、中間語109の例を示したものである。前記実施の形態1での図6と同様に、本実施の形態でも機械語に近いレベルの中間語を想定している。命令と呼ばれるメモリセルを、2重リンクでリスト状に繋げる形で構成している点も図6と同様である。
図14の中間語109は、図13のソースプログラム106の行1301〜行1305の部分に相当するものである。命令1401(cmp)は、変数aと変数bを比較(compare)することを示す。命令1402(bne)は、前記比較の結果、aとbが等しくない(Not Equal)場合に、オペランドのポインタで指される(リンクされる)命令1405へ分岐することを示す。そうではない(等しい)場合は、直後の命令1403に制御を移す(fall-through)。命令1403は、図13のソースプログラム106の行1302の実行文1に対応する文である。ここでは1つの命令で表されているが、複数の命令から構成されている場合もある。命令1404(bra)は、オペランドのポインタで指される命令1406へ無条件分岐することを示す。
図15は、本実施の形態での、図4のステップ405での耐タンパコード挿入処理の詳細な例を表すフローチャートである。まずステップ1501で、中間語109内の全命令の処理済フラグをOFFにする。次にステップ1502において、中間語109内の最初の命令を取り出し、それをtとする。次にステップ1503で、tがNULLかどうかを調べる。NULLであれば命令がすべて処理済みなので終了する。NULLでなければステップ1504へ進み、tが条件分岐命令かどうかを調べる。条件分岐命令でなければステップ1507へ進み、tの次の命令を新たにtとし、ステップ1503から繰り返す。ステップ1504でtが条件分岐命令であれば、ステップ1505でtの処理済フラグがONかどうかを調べる。ONであればステップ1507へ進み、ONでなければステップ1506へ進む。
ステップ1506では、以下の(1)〜(8)の処理を行う。
(1)tの直後の命令をsとする。
(2)tの直後に、tの分岐条件を反転した条件分岐命令を挿入し、これをuとする。
(3)uの直後に、ラベル_errorへの無条件分岐命令を挿入し、これをvとする。
(4)tの分岐先の命令(wとする)の直前に、tの分岐条件を反転した条件分岐命令を挿入し、これをxとする。
(5)tの分岐先をxに変更する。
(6)uの分岐先をsに変更する。
(7)xの分岐先をvに変更する。
(8)s、t、u、v、w、xの処理済フラグをONにする。
前記(1)〜(8)の処理終了後、ステップ1507へ進む。
(1)tの直後の命令をsとする。
(2)tの直後に、tの分岐条件を反転した条件分岐命令を挿入し、これをuとする。
(3)uの直後に、ラベル_errorへの無条件分岐命令を挿入し、これをvとする。
(4)tの分岐先の命令(wとする)の直前に、tの分岐条件を反転した条件分岐命令を挿入し、これをxとする。
(5)tの分岐先をxに変更する。
(6)uの分岐先をsに変更する。
(7)xの分岐先をvに変更する。
(8)s、t、u、v、w、xの処理済フラグをONにする。
前記(1)〜(8)の処理終了後、ステップ1507へ進む。
図16は、図14の中間語109に対して図15の耐タンパコード挿入処理を行った後の中間語109の例を示すものである。以下に、図15の処理フローに従って該中間語109が生成される過程を示す。
ステップ1502で最初の命令(命令1401)を取り出し、それをtとする。ステップ1503でtがNULLかどうかを調べる。tはNULLではないのでステップ1504へ進み、tが条件分岐命令かどうかを調べる。tは条件分岐命令ではないのでステップ1507へ進み、tの次の命令(命令1402)を新たにtとする。再びステップ1503でtがNULLかどうかを調べる。tはNULLではないので、ステップ1504でtが条件分岐命令かどうかを調べる。tは条件分岐命令なのでステップ1505へ進み、処理済フラグがONかどうかを調べる。処理済フラグはOFFなのでステップ1506へ進む。
ステップ1506では、以下の(1)〜(8)の処理を行う。
(1)tの直後の命令(命令1403)をsとする。
(2)tの直後にtの分岐条件を反転した条件分岐命令を挿入し、これをuとする。tの分岐条件は「ne(Not Equal)」なので、これを反転した条件は「eq(Equal)」である。図16の命令1601がuに相当する。
(3)uの直後に、ラベル_errorへの無条件分岐命令を挿入し、これをvとする。図16の命令1602がvに相当する。
(4)tの分岐先の命令は図14の命令1405なので、これをwとし、wの直前にtの分岐条件を反転した条件分岐命令を挿入し、これをxとする。図16の命令1603がxに相当する。
(5)t(命令1402)の分岐先をx(命令1603)に変更する。
(6)u(命令1601)の分岐先をs(命令1403)に変更する。
(7)x(命令1603)の分岐先をv(命令1602)に変更する。
(8)s、t、u、v、w、xの処理済フラグをONにする。
(1)tの直後の命令(命令1403)をsとする。
(2)tの直後にtの分岐条件を反転した条件分岐命令を挿入し、これをuとする。tの分岐条件は「ne(Not Equal)」なので、これを反転した条件は「eq(Equal)」である。図16の命令1601がuに相当する。
(3)uの直後に、ラベル_errorへの無条件分岐命令を挿入し、これをvとする。図16の命令1602がvに相当する。
(4)tの分岐先の命令は図14の命令1405なので、これをwとし、wの直前にtの分岐条件を反転した条件分岐命令を挿入し、これをxとする。図16の命令1603がxに相当する。
(5)t(命令1402)の分岐先をx(命令1603)に変更する。
(6)u(命令1601)の分岐先をs(命令1403)に変更する。
(7)x(命令1603)の分岐先をv(命令1602)に変更する。
(8)s、t、u、v、w、xの処理済フラグをONにする。
次にステップ1507へ進み、tの次の命令(命令1601)を新たにtとし、ステップ1503へ戻る。ステップ1503で再びtがNULLかどうかを調べ、tはNULLではないのでステップ1504へ進み、tが条件分岐命令かどうかを調べる。t(命令1601)は条件分岐命令なのでステップ1505へ進み、tの処理済フラグがONかどうかを調べる。命令1601の処理済フラグは、前記ステップ1506の(8)の処理でONにされているので、ステップ1507へ進み、tの次の命令(命令1602)が新たにtに設定され、再びステップ1503からの処理を行う。この時点で、当該処理中の中間語109に条件分岐命令であって処理済フラグがOFFの命令は存在しないため、以降の処理ではステップ1506に入ることはなく、耐タンパコードの挿入処理は行われない。
図17は、図13のソースプログラム106を入力としたときの、従来技術のコンパイラの出力するアセンブリ言語プログラムの例である。まず、「cmp Ra,Rb」命令(命令1701)により、変数aの値を保持するレジスタRaと、変数bの値を保持するレジスタRbの値を比較し、その結果を条件コードレジスタに格納する。次の命令1702では、該条件コードレジスタの値を調べ、比較結果が等しくない場合はラベルL1(命令1705)へ分岐する。そうではない(等しい)場合は直後の命令へ制御を移し、実行文1(命令1703)を実行して、命令1704でラベルL2(命令1707)へ分岐する。命令1702でL1へ分岐した場合、実行文2(命令1706)を実行した後、直後の命令へ制御を移す。
図18は、図13のソースプログラム106を入力としたときの、本実施の形態での言語ツール108が出力するアセンブリ言語プログラム206の例である。ここでは図13のソースプログラム106の行1301のif文に対応する条件分岐命令が命令1802〜命令1803のように、2つ連続して並べられている。これにより、もし最初の条件分岐命令が、誤動作解析アタックなどの攻撃により不正にfall-through分岐した場合でも、2番目の条件分岐命令で再度条件判定が行われるため、誤動作の可能性が低くなる。
なお、図18のアセンブリ言語プログラム206では、命令1802〜命令1803に示すように、分岐条件を反転させて条件分岐を連続して行うようにしているが、分岐条件を反転させずに連続して行うようなコードを生成してもよい。このときのアセンブリ言語プログラム206の例を図19に示す。
命令1902〜命令1903は同じ分岐条件の条件分岐命令を連続して並べている。この場合も、最初の条件分岐命令1902が誤動作解析アタックにより不正にfall-through分岐したとしても、次の条件分岐命令1903で再度同じ条件判定が行われるため、誤動作の可能性が低くなる。命令1902又は命令1903で分岐しなかった場合、命令1905でさらに同様の分岐条件で判定し、ここで分岐する判定となった場合はエラー処理(error())へ分岐する。また、逆に最初の条件分岐命令1902が誤動作解析アタックにより不正にラベルL1(命令1908)へ分岐したとしても、命令1909で再び分岐条件を調べ、正しい分岐方向であるラベルL3(命令1904)に戻れるようにする。命令1909にてL3に分岐しなかった場合は、命令1910でさらに同じ分岐条件でチェックを行い、正しい分岐方向に戻れていない場合はエラー処理(error())へ分岐する。
図18及び図19のアセンブリ言語プログラム206の例では、条件分岐命令を2つ並べて多重化しているが、条件分岐命令を3つ以上並べて多重化することも可能である。
図20は、本実施の形態での言語ツール108に、さらに前記実施の形態1で示した多重条件分岐の分岐経路検証を行うコードを挿入する処理を組み合わせた場合に、図5のソースプログラム106を入力としたときの言語ツール108が出力するアセンブリ言語プログラム206の例を示したものである。実施の形態1での言語ツール108にて耐タンパコード挿入処理を行った出力結果である図10のアセンブリ言語プログラム206に比べて、ラベル2006と命令2007、ラベル2017と命令2018、及び命令2005、命令2012、命令2016、命令2027の各条件分岐命令が、本実施の形態での言語ツール108での処理により追加で挿入されている。
なお、図20において、本実施の形態での言語ツール108により多重化される条件分岐命令は、図5のソースプログラム106において存在した条件分岐命令に対応するもののみであり、前記実施の形態1での言語ツール108での処理により挿入された条件分岐命令(命令2021、命令2029)については多重化されていないが、該条件分岐命令を多重化することも可能である。
実施の形態1と同様に、本実施の形態においても、耐タンパコードを挿入する関数をソースプログラム106中で#pragma指示文により指定する。コンパイラ起動コマンドに付加するコンパイルオプションによって指定することもできる。また、耐タンパコードを挿入するかどうかを関数毎ではなくさらに細かい粒度で指定することも可能である。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理の処理済フラグがONになっている中間語109の命令については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、条件分岐判定の多重化といった、ユーザが手作業で作成するのが難しい耐タンパ性を持つ実行可能プログラム107を自動的に生成することができ、耐タンパ性を持つアプリケーションの開発生産性が向上する。
<実施の形態3>
以下、本発明の実施の形態3として、関数呼び出し時のパラメータ内容チェックを行う実行可能プログラムを生成する言語ツールの例について説明する。
以下、本発明の実施の形態3として、関数呼び出し時のパラメータ内容チェックを行う実行可能プログラムを生成する言語ツールの例について説明する。
本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。また、本実施の形態での言語ツール108の構成と処理概要の例は図2と同じである。また、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。図4のステップ405の耐タンパコード挿入処理の詳細は、実施の形態1及び実施の形態2でのものとは異なるため、図21〜図24を用いてさらに詳しく説明する。
図21は、本実施の形態での言語ツール108への入力となる、ソースプログラム106の例である。関数main(行2101〜行2106)から、行2104においてarg1、arg2を実引数として関数sub(行2108〜行2111)を呼び出していることを示している。
図22は、本実施の形態での言語ツール108により生成される、図4のステップ405での耐タンパコード挿入処理を行う前の、中間語109の例を示したものである。コンパイラが生成する中間語には、一般にソースプログラムに近いレベルのものから、機械語に近いレベルのものまで存在するが、本実施の形態ではソースプログラムに近いレベルのものを想定している。中間語109はノードと呼ばれるメモリセルを2重リンクでツリー状に接続する形で構成しており、ソースプログラム106の1つの関数が1つのツリーに対応し、ツリーのルートに当たるノード同士は2重リンクでリスト状につなげる形で構成している。図中の矢印はノード間のリンクを表す。
図22の中間語109は、図21のソースプログラム106に対応するものである。ノード2201は関数mainの先頭文(行2101)を表すノードである。ノード2201には、関数内の最初の実行文(行2103)を示すstmtノード2202が接続されている、stmtノード2202には、前記実行文(行2103)の処理内容を表すノード2203と、次の実行文(行2104)を示すstmtノード2204が接続されている。同様に、stmtノード2206はstmtノード2204の次に実行される文(行2105)を示す。
stmtノード2204には、行2104の処理内容である関数呼び出しを示すcallノード2205が接続されている。callノード2205には、呼び出し先の関数subを表すidノード2207と、実引数のリストを示すarg_listノード2208とが接続されている。arg_listノード2208には、関数呼び出しの実引数arg1、arg2を表すidノード2210とidノード2211とが接続されている。
ノード2212は、次の関数subの先頭文(行2108)を表すノードである。ノード2212には、関数の仮引数リストを示すparamノード2213と、関数内の最初の実行文(行2110)を示すstmtノード2214とが接続されている。paramノード2213には、仮引数a、bを表すidノード2215とidノード2216とが接続されている。関数の先頭文を示すノード2201とノード2212は2重リンクでリスト状につなげる形で構成している。
図23は、本実施の形態での、図4のステップ405での耐タンパコード挿入処理の詳細な例を表すフローチャートである。
まずステップ2301で、中間語109の最初の文のノードを取り出し、それをtとする。次にステップ2302で、tがNULLかどうかを調べる。NULLであればノードがすべて処理済みなので終了する。NULLでなければステップ2303へ進み、tが関数先頭文のノードかどうかを調べる。関数先頭文のノードでなければステップ2306へ進む。関数先頭文のノードであればステップ2304へ進み、該関数に仮引数があるかどうかを調べる。仮引数が無ければステップ2306へ進み、仮引数があればステップ2305へ進む。
ステップ2305では、以下の(1)〜(2)の処理を行う。
(1)前記仮引数をpar1、par2、...、parNとしたとき、
if (par1+par2+...+parN != sum) goto error
という実行文に相当するノードを、該関数の先頭の実行文のノードとして挿入する。元々の先頭の実行文のノードは、新たに挿入した前記ノードの次の実行文として接続する。
(2)該関数の仮引数の末尾に仮引数sumを追加する。
(1)前記仮引数をpar1、par2、...、parNとしたとき、
if (par1+par2+...+parN != sum) goto error
という実行文に相当するノードを、該関数の先頭の実行文のノードとして挿入する。元々の先頭の実行文のノードは、新たに挿入した前記ノードの次の実行文として接続する。
(2)該関数の仮引数の末尾に仮引数sumを追加する。
次にステップ2306で、tが関数呼び出し文のノードかどうかを調べる。関数呼び出し文のノードではない場合はステップ2309へ進み、tの次の文のノードを新たにtとし、ステップ2302から繰り返す。tが関数呼び出し文のノードの場合、ステップ2307へ進み、該関数呼び出しに実引数があるかどうかを調べる。実引数が無ければステップ2309へ進む。実引数がある場合はステップ2308へ進み、実引数をarg1、arg2、...、argNとしたとき、arg1+arg2+...+argNを実引数の末尾に追加してステップ2309へ進む。
図24は、図22の中間語109に対して図23の耐タンパコード挿入処理を行った後の中間語109の例を示すものである。以下に、図23の処理フローに従って該中間語109が生成される過程を示す。
まずステップ2301で、図22の中間語109から最初のノード(ノード2201)を取り出し、これをtとする。次にステップ2302で、tがNULLかどうかを調べる。tはNULLではないのでステップ2303へ進み、tが関数先頭文のノードかどうかを調べる。tは関数mainの先頭文のノードなのでステップ2304へ進み、該関数に仮引数があるかどうかを調べる。該関数には仮引数が無いのでステップ2306へ進み、tが関数呼び出し文のノードかどうかを調べる。tは関数呼び出し文のノードではないのでステップ2309へ進み、tの次の文のノード(ノード2202)を新たにtとする。ノード2202は関数先頭文でも関数呼び出し文でもないので何も処理されず、ステップ2309でノード2204を新たにtとする。
tは関数先頭文のノードではないので、ステップ2303からステップ2306に移るところまではノード2202の場合と同様だが、ノード2204にはcallノード2205が接続されており、関数呼び出し文のノードなのでステップ2307へ進み、該関数呼び出し文に実引数があるかどうかを調べる。callノード2205には実引数リストのarg_listノード2208が接続されており、実引数があるので、ステップ2308へ進む。
ステップ2308では、前記実引数がarg1、arg2なので、arg1+arg2を実引数リストの末尾に追加して(ノード2401〜ノード2403)、ステップ2309へ進む。次にtの次の文(ノード2206)を新たなtとする。以降、関数main内の文のノードは、ノード2202と同様に関数先頭文でも関数呼び出し文でもないので、耐タンパコード挿入処理は行われない。
関数main内の実行文の処理が終了すると、次の関数の処理に移り、ノード2212をtとして、ステップ2302でtがNULLかどうかを調べる。tはNULLではないのでステップ2303へ進み、tが関数先頭文のノードかどうかを調べる。tは関数subの先頭文のノードなのでステップ2304へ進み、該関数に仮引数があるかどうかを調べる。ノード2212にはparamノード2213が接続されており、仮引数があるので、ステップ2305へ進む。
ステップ2305では、以下の(1)〜(2)の処理を行う。
(1)paramノード2213に接続されているidノード2215、idノード2216より、仮引数がa、bなので、if (a+b != sum) goto errorという実行文に相当するノード(ノード2405〜ノード2413)を、関数subの先頭の実行文のノードとして挿入する。元々の先頭の実行文のstmtノード2214は、新たに挿入したstmtノード2405の次の実行文として接続する。
(2)関数subの仮引数の末尾に仮引数sum(ノード2404)を追加する。
(1)paramノード2213に接続されているidノード2215、idノード2216より、仮引数がa、bなので、if (a+b != sum) goto errorという実行文に相当するノード(ノード2405〜ノード2413)を、関数subの先頭の実行文のノードとして挿入する。元々の先頭の実行文のstmtノード2214は、新たに挿入したstmtノード2405の次の実行文として接続する。
(2)関数subの仮引数の末尾に仮引数sum(ノード2404)を追加する。
次にステップ2306へ進み、tが関数呼び出し文のノードかどうかを調べる。tは関数呼び出し文のノードではないのでステップ2309へ進み、tの次の文のノード(ノード2214)を新たにtとする。以降、関数sub内の文には関数先頭文も関数呼び出し文もないので、ステップ2305及びステップ2308に入ることはなく、耐タンパコードの挿入処理は行われない。
図25は、図21のソースプログラム106を入力としたときの、従来技術のコンパイラの出力するアセンブリ言語プログラムの例である。まず、関数main内で、「mov arg1,r0」命令(命令2503)でレジスタr0にarg1の値を、「mov arg2,r1」命令(命令2504)でレジスタr1にarg2の値をそれぞれ設定する。次に、「push」命令(命令2505、命令2506)でレジスタr0、r1の値をパラメータとしてスタックに積んで呼び出し先の関数に渡せるようにして、「jsr _sub」命令(命令2507)で関数subを呼び出している。関数subでは、「pop」命令(命令2510、命令2511)により、渡されたパラメータの値をレジスタに戻している。
図26は、図21のソースプログラム106を入力としたときの、本実施の形態での言語ツール108が出力するアセンブリ言語プログラム206の例である。図26のアセンブリ言語プログラム206では、図21のソースプログラム106の行2104の関数subの呼び出しに対応する命令(命令2610)に対して、命令2605、命令2606により実引数arg1、arg2の値を加算したものをレジスタr2に設定し、それを命令2609の「push」命令により末尾の実引数としてスタックに積んで関数subに渡している。
呼び出された関数subの処理では、まず命令2613〜命令2615の「pop」命令によりレジスタr0、r1、r2にパラメータの値を戻す。次に、命令2616、命令2617により、仮引数a、bに相当するパラメータの値(r0、r1)をレジスタr3に足し合わせる。次に、命令2618により、追加された仮引数sumに相当するパラメータの値(r2)と前記r3の値を比較している。前記比較結果が等しくない(ne)場合は命令2619によりエラー処理(error())へ分岐する。これにより、関数呼び出し時に、誤動作解析アタックなどの攻撃により不正にパラメータの値が変更された場合はエラー処理へ制御が移るため、誤動作の可能性が低くなる。
実施の形態1と同様に、本実施の形態においても、耐タンパコードを挿入する関数をソースプログラム106中で#pragma指示文により指定する。コンパイラ起動コマンドに付加するコンパイルオプションによって指定することもできる。また、耐タンパコードを挿入するかどうかを関数毎ではなくさらに細かい粒度で指定することも可能である。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理の処理済フラグがONになっている中間語109の命令については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、関数呼び出し時のパラメータ内容チェックといった、ユーザが手作業で作成するのが難しい耐タンパ性を持つ実行可能プログラム107を自動的に生成することができ、耐タンパ性を持つアプリケーションの開発生産性が向上する。
<実施の形態4>
本発明の実施の形態4として、ループ処理についての複数パターンのコード生成による電流特性複雑化を行うことにより、実行時の電流特性の特徴を薄めるような機械語を生成する言語ツールの例について説明する。
本発明の実施の形態4として、ループ処理についての複数パターンのコード生成による電流特性複雑化を行うことにより、実行時の電流特性の特徴を薄めるような機械語を生成する言語ツールの例について説明する。
ソースプログラムにおけるループ処理(C言語におけるfor文、while文、do while文等)をそのまま機械語に翻訳して実行可能プログラムを生成すると、当該実行可能プログラムは同じような処理を繰り返し実行するために、実行時の電流特性に一定のパターン化した特徴が現れる。このような特徴的な電流特性は、攻撃者に対して不正な動作解析の機会を与える危険性が高い。
図27は、ループ処理を記述したC言語のソースプログラムの例であり、単純なデータ転送処理を繰り返し行うものである。図28は、図27のソースプログラムを従来の言語ツールにてコンパイルした結果の機械語命令列をアセンブラ記述により表した例である。図28において、(1)〜(3)で表された処理ブロックのうち、(2)の処理ブロックはループ処理の内容である図27の行2702のデータ転送処理を実行する部分となる。図29は、図28のプログラムを実行した場合の処理順序の例を表した図であり、図28における(2)のデータ転送処理が繰り返し実行されることを表している。この場合、同じような電流特性が短い周期で繰り返され、その特性からループ処理であることが推定される危険性がある。
そこで、本実施の形態での言語ツールでは、ループ内の処理について、同じ内容の処理を複数パターンの命令列で展開することにより、処理を複雑化させる。図30は、図27のソースプログラムについて、ループ処理を複雑化させてコンパイルした結果の機械語命令列をアセンブラ記述により表した例である。図30において、(1)〜(10)で表された処理ブロックのうち、(2)〜(9)の処理ブロックは、ループ処理の内容である図27の行2702のデータ転送処理をそれぞれ異なる複数パターンの命令列で表現したものである。図31は、図30のプログラムを実行した場合の処理順序の例を表した図であり、図30における(2)〜(9)の処理ブロックが順に実行されることを表している。
これにより、ループ毎に同じ命令列の繰り返しではなく、すべて異なる複数パターンの命令列により処理を行うことになり、単純なループ処理を実行した場合の電流特性の規則性を希薄化することができる。よって実行時には一見不規則な電流特性となり、ループ処理以外の他の処理の実行時と見分けが付きにくくなり、攻撃者からの不正な動作解析を困難にすることができる。
このような機械語の命令列の作成は、ユーザによる手作業でも可能ではあるが、アセンブリ言語等の低級言語の知識を要求するためそのハードルは高く、工数も要する。よって、言語ツールにループ内の処理を自動的に複雑化する機能を追加することによって、自動的にこのような機械語の命令列が生成されるようにする。この場合、ある処理に対して複数パターンの命令列を作成できるように、言語ツールは多くの処理パターンを内部に記憶しておき、対象となるループ処理に対して必要な数だけパターンを埋め込むようにする。
以下に、本実施の形態での言語ツールの具体的な内容について説明する。本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。また、本実施の形態での言語ツール108の構成と処理概要の例は図2と同じである。また、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。
図4のステップ405の耐タンパコード挿入処理によって、ソースプログラム106中のループ処理がどのように複雑化されるかを、簡単な例を挙げて説明する。一般的に、ソースプログラム106中に記述されるループ処理は、ループ回数が多いために、全てのループ処理を図30に示す例のように一度に展開すると、プログラムサイズが発散してしまう場合がある。また、ループ回数があらかじめ固定ではなく、実行時までループ回数が確定しない場合も多く、ループ内の処理を全て展開することは現実的ではない。
そこで、図30に示す例のようにループ内の処理を一律に全パターンで展開するのとは別に、下記のような手順により効果的に複数パターンに展開する。
(1)ユーザが指定する数に達するまで、ループ内処理を複数パターンの命令列で作成する。
(2)作成された複数パターンの命令列の実行をswitch文のような形式で振り分ける。
(3)前記switch文での振り分けに使用する変数とその計算式を設定する。
(4)前記switch文をソースプログラム106に記述されているループ回数だけループさせる。
(1)ユーザが指定する数に達するまで、ループ内処理を複数パターンの命令列で作成する。
(2)作成された複数パターンの命令列の実行をswitch文のような形式で振り分ける。
(3)前記switch文での振り分けに使用する変数とその計算式を設定する。
(4)前記switch文をソースプログラム106に記述されているループ回数だけループさせる。
このようにしてループ処理を複数パターンの命令列に展開する場合のコード生成例を図32に示す。図32は、C言語によりループ処理を記述したソースプログラム106と、当該ソースプログラム106を本実施の形態でのコンパイラ201によってコンパイルした結果の例を表している。なお、コンパイルした結果については、説明を簡便にするためにアセンブリ言語ではなくC言語による擬似プログラムの形式で表している。
ソースプログラム106の行3202〜行3204は、単純なデータ転送を行うループ処理の例を表している。当該ループ処理が、処理内容を知られたくないループである場合、ユーザは、行3201および行3205の拡張言語仕様#pragmaにて、耐タンパコード挿入処理の対象範囲として当該ループ処理を指定することができる。図33は、C言語でソースプログラム106を記述する場合の拡張言語仕様#pragmaによる書式の例である。ここで、ループの先頭では、書式3301の#pragmaにて当該ループ処理を複数パターンの命令列で展開する際の最大サイズを指定することができる。これにより、プログラムサイズが発散してしまうのを避けることができる。
前記(1)の手順により、行3203の処理は、行3216〜行3223のように、行3201の#pragmaにて指定されている最大サイズである8つの処理パターンに展開されている。ここで、行3216〜行3223の「転送パターンx」という処理は、行3203のデータ転送処理と同じ動作内容を、それぞれ異なる命令列によって実現するものを表している。
また、前記(2)の手順により、行3214のswitch文で行3216〜行3223の処理が振り分けられるようになっている。また、前記(3)の手順により、行3211、行3225で、行3214のswitch文で使用する変数xの設定と値の更新を行うようになっている。また、前記(4)の手順により、行3212のfor文で、行3214〜行3225の処理を、ソースプログラム106における行3202で指定されているループ回数と同じ回数だけループさせている。
このような処理により、行3212〜行3226のループ処理を実行した場合のループ毎の処理時間や電流特性は異なることになり、それぞれが同じ内容の処理であることが悟られにくくなる。この場合、各データ転送パターンを順に実行するだけでも、ループ内の処理の電流特性周期は単純に8倍になるが、行3225での変数xの値の更新方法を工夫することにより、電流特性周期をさらに大きくすることができ、単純なデータ転送処理であることを隠蔽することができる。
ここで、変数xは、行3214のswitch文による処理の振り分けのために用いる判定値なので、見かけ上ランダムな値になるのが望ましく、見かけ上の規則性がない、もしくは薄くなるように行3225で更新することができるのであれば、「その時点で値が確定している何らかのデータ」を用いればよい。判定値の更新方法として、例えば以下のような方法が考えられる。
(a)判定値のテーブルを別途用意する。またはテーブルに相当するものを利用する。
(b)その時点で設定されているレジスタ等の値を利用する。
(a)判定値のテーブルを別途用意する。またはテーブルに相当するものを利用する。
(b)その時点で設定されているレジスタ等の値を利用する。
以下に、前記(a)、(b)の更新方法によって判定値を更新してループ処理を複雑化した場合の例を説明する。図34は、前記(a)の、判定値のテーブルまたはそれに相当するものを利用して判定値を更新してループ処理を複雑化した場合の例を、C言語のソースプログラムのイメージで表した図である。
ここで、処理の振り分けに際しては、判定値のテーブルを実際に使用するのが最も簡単ではあるが、当該テーブルをメモリ上に保持するのではメモリの使用効率が悪くなる。振り分けに際しては実際に判定値のテーブルを用意する必要はなく、テーブルに相当するものとして例えば、ターゲットマイコン208のプログラム格納領域302に格納されている実行可能プログラム107の命令コード自体を判定のための要素としても、電流特性の周期性がない処理の振り分けが可能である。図34のコンパイル結果では、行3425にて実行可能プログラム107の命令コードの値を順次参照し、行3414ではその値を利用して0〜7の数値を算出し、switch文による処理の振り分けを行っている。
図35は、前記(b)の、レジスタの設定値を利用して判定値を更新してループ処理を複雑化した場合の例を、C言語のソースプログラムのイメージで表した図である。図35のコンパイル結果では、行3525にて実行時点におけるレジスタの値を取得して、行3514ではその値を利用して0〜7の値を算出してswitch文による処理の振り分けを行うことにより、ループ処理の電流特性の規則性を排除している。なお、行3525において参照するレジスタは、汎用レジスタやシステムレジスタなど全てのレジスタを対象にすることができる。
判定値の更新方法は上述した方法だけに限られず、これ以外にも種々の方法が考えられる。例えば、判定値の規則性の周期が大きくなるような計算式によって判定値を更新する方法などが考えられる。
なお、本実施の形態での言語ツール108では、ソースプログラム106において耐タンパコード挿入処理の対象となるループ処理を指定する方法として、図33に示す拡張言語仕様#pragmaによりループ処理毎に指定する方法をとっているが、実施の形態1と同様に、コンパイラ起動コマンドに付加するコンパイルオプションによって一括指定する方法をとることも可能である。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理によって挿入された中間語109については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、単純なループ処理を複数の処理パターンによって展開して複雑化することで実行時の電流特性の規則性を希薄にし、消費電流の解析による処理内容の推定・解析を困難にするといった、耐タンパ性を持つプログラムを生成することができる。また、このようなユーザが手作業で作成することが難しいプログラムを自動的に生成することができ、耐タンパ性を持つプログラムの開発生産性が向上する。また、本実施の形態での言語ツール108によってコンパイルを実行することにより、高級言語で記述された既存のソースプログラムをそのまま耐タンパ性を有するセキュアなプログラムへ移植することも容易となる。
<実施の形態5>
本発明の実施の形態5として、条件分岐の各分岐経路の実行時間を均一化することによる電流特性近似化を行うことにより、実行時の電流特性の特徴を薄めるような機械語を生成する言語ツールの例について説明する。
本発明の実施の形態5として、条件分岐の各分岐経路の実行時間を均一化することによる電流特性近似化を行うことにより、実行時の電流特性の特徴を薄めるような機械語を生成する言語ツールの例について説明する。
ソースプログラム106に条件分岐(C言語におけるif文、switch文等)があり、分岐先の処理が例えば処理Aと処理Bである2通りの分岐経路がある場合、処理Aと処理Bの実行時間が異なると、実行時の電流特性から「どちらの処理を行った」ということを推測される危険性がある。特に、機密情報の種類に応じて処理を分ける場合などにおいて危険性が高い。
図36は、条件分岐処理を記述したC言語のソースプログラムの例であり、3つのデータ転送処理を行う分岐経路1と1つのデータ転送処理を行う分岐経路2とを有する。ここでは1命令あたりの実行サイクル数を例えば1と仮定して説明する。図37は、図36のソースプログラムを従来の言語ツールにてコンパイルした結果の機械語命令列をアセンブラ記述により表した例である。図37において、分岐経路1は実行サイクル数が4であり、分岐経路2は実行サイクル数が1となっており、分岐経路によって処理の実行時間が異なることから、処理内容を推測される危険性がある。
そこで、本実施の形態での言語ツールでは、実行しても実行可能プログラムの動作内容に影響を与えないような処理を埋め込むなどによって、各分岐経路の処理の実行時間が均一化されるように機械語の命令列を生成する。これにより、実行可能プログラムの実行時には、各分岐経路の処理の実行時間が近い値となり、また電流特性も近似したものになるため、攻撃者からの不正な動作解析を困難にすることができる。
このような機械語の命令列の作成は、ユーザによる手作業でも可能ではあるが、低級言語の知識を要求するためそのハードルは高く、工数も要する。よって、言語ツールに各分岐経路の処理の実行時間を均一化する機能を追加することによって、自動的にこのような機械語の命令列が生成されるようにする。その際、分岐経路の実行時間は、分岐経路中の各命令の実行サイクル数によって計算する。言語ツールは、各命令の実行サイクル数を記憶しておき、各分岐経路内の命令の実行サイクル数の合計が一致する(あるいは可能な限り近い値になる)ように自動的に命令列を生成する。
以下に、本実施の形態での言語ツールの具体的な内容について説明する。本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。また、本実施の形態での言語ツール108の構成と処理概要の例は図2と同じである。また、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。
図4のステップ405の耐タンパコード挿入処理によって、ソースプログラム106中の条件分岐処理の実行時間がどのように均一化されるかを、簡単な例を挙げて説明する。なお、ここでは説明を簡単にするために各命令の実行サイクル数は同じであるとする。
図38は、C言語により条件分岐処理を記述したソースプログラム106の例と、当該ソースプログラム106を従来のコンパイラによりコンパイルした結果の例と、本実施の形態でのコンパイラ201によってコンパイルした結果の例を表している。図中、斜字体で記載されている部分は、本実施の形態でのコンパイラ201の耐タンパコード挿入処理によって生成された命令列を表している。なお、ここでは1命令あたりの実行サイクル数を例えば1と仮定して説明する。
ソースプログラム106の行3802〜行3809は、条件分岐処理の例を表している。当該条件分岐処理が、処理内容を知られたくない条件分岐である場合、ユーザは実施の形態4と同様に、行3801および行3810の拡張言語仕様#pragmaにて、耐タンパコード挿入処理の対象範囲として当該条件分岐処理を指定することができる。図39は、C言語でソースプログラム106を記述する場合の拡張言語仕様#pragmaによる書式の例である。
図38において、本実施の形態でのコンパイラ201によるコンパイル結果では、行3828〜行3831のように、ソースプログラム106のelse節における行3808の加算処理を、対応する分岐経路の処理である行3803〜行3805の加算処理のコンパイル結果である行3823〜行3826と同様に3つの加算処理として実現し、両方の分岐経路の実行サイクル数の合計が4サイクルで一致するように命令列が生成されている。ここで、行3808における「3を加算する」という処理と、行3828〜行3830における「1を加算する」という処理を3回行うことは、最終的な動作内容としては同じである。
また、対象の条件分岐処理がelse節を有しないif文である場合は、使用しないダミーデータに対して条件分岐先の処理と同様の処理を行うelse節を追加するようにすれば、簡単に前記と同様の内容を実現することができる。図40は、C言語によりelse節を有しないif文を記述したソースプログラム106の例と、当該ソースプログラム106を従来のコンパイラによりコンパイルした結果の例と、本実施の形態でのコンパイラ201によってコンパイルした結果の例を表している。図中、斜字体で記載されている部分は、本実施の形態でのコンパイラ201の耐タンパコード挿入処理によって生成された命令列を表している。
図40において、本実施の形態でのコンパイラ201によるコンパイル結果では、行4025以下のelse節が追加されており、当該else節では行4026にて、対応する分岐経路中の処理である行4023のデータ設定処理と同様のデータ設定処理を、使用しないダミーデータに対して行い、両方の分岐経路の実行サイクル数の合計が2サイクルで一致するように命令列が生成されている。なお、ここでは1命令あたりの実行サイクル数を例えば1と仮定して説明する。
本実施の形態では、if〜else文によって2つの分岐経路を有する条件分岐処理を例として挙げているが、例えばif〜else if文や、switch文によってソースプログラム106において分岐経路が2つ以上となるような場合も前記と同様な処理を行うことが可能である。
なお、本実施の形態での言語ツール108では、ソースプログラム106において耐タンパコード挿入処理の対象となる条件分岐処理を指定する方法として、図39に示す拡張言語仕様#pragmaにより条件分岐処理毎に指定する方法をとっているが、実施の形態4と同様に、コンパイラ起動コマンドに付加するコンパイルオプションによって一括指定する方法をとることも可能である。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理によって挿入された中間語109については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、条件分岐処理に対して冗長な命令を追加することで各条件分岐処理の実行時間を均一化し、実行時の電流特性を近似させることによって、消費電流の解析による処理内容の推定・解析を困難にするといった、耐タンパ性を持つプログラムを生成することができる。また、このようなユーザが手作業で作成することが難しいプログラムを自動的に生成することができ、耐タンパ性を持つプログラムの開発生産性が向上する。また、本実施の形態での言語ツール108によってコンパイルを実行することにより、高級言語で記述された既存のソースプログラムをそのまま耐タンパ性を有するセキュアなプログラムへ移植することも容易となる。
<実施の形態6>
本発明の実施の形態6として、命令コードを積算したチェックサムの期待値を算出し、実行時の命令コードの積算値とハードウェアにより比較することでプログラムの誤動作を検出または防止することを可能とする機械語を生成する言語ツールの例について説明する。
本発明の実施の形態6として、命令コードを積算したチェックサムの期待値を算出し、実行時の命令コードの積算値とハードウェアにより比較することでプログラムの誤動作を検出または防止することを可能とする機械語を生成する言語ツールの例について説明する。
プログラムの実行時に、ハードウェアを用いてソースプログラムにおける所定の領域の命令コードの積算値(チェックサム)を算出しその期待値と比較することによって、期待値と異なる場合は命令コードの変化や命令コードのスキップが発生したと推定され、プログラムの誤動作を検出または防止することが可能である。
このようなチェックサムによる検証の際には、所定の領域の命令コードを0から積算し、あらかじめ設定されている期待値と比較する方法と、積算結果が所定の値(例えば0)になるように積算の初期値を設定し、積算結果が所定の値になることを確認する方法とが考えられる。以下では、前記期待値および初期値を積算設定値と総称する。
チェックサムによる検証を行うためには、プログラムに、チェックサム検証のためのハードウェアのレジスタ情報の設定や、所定の領域での積算開始・終了の指示などをハードウェアに対して行う命令列を埋め込む必要がある。このような機械語の命令列の作成は、ユーザによる手作業でも可能ではあるが、低級言語の知識を要求するためそのハードルは高く、工数も要する。
また、前述の積算設定値は、事前にレジスタ等に設定しておく必要がある。ここで、積算設定値の算出については、ユーザが人手により算出する方法や、プログラムの1回目の実行時に算出してそれを記憶しておき、2回目以降の実行時には記憶した値を用いる方法などが考えられる。しかし、ユーザが人手により算出する場合は、開発工数が大きく増加してしまう。また、プログラムの1回目の実行時に算出する方法では、1回目の実行時にはチェックサムによる検証ができないことになる。
よって、言語ツール108にチェックサム検証のためのハードウェアのレジスタ情報の設定、所定の領域のチェックサムの積算開始と積算終了・検証実行の指示をハードウェアに対して行う命令列を作成する機能、および当該所定の領域の積算設定値を算出する機能を追加することによって、チェックサム検証を行うことを可能とする機械語の命令列が自動的に生成されるようにする。
以下に、本実施の形態での言語ツールの具体的な内容について説明する。本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。また、本実施の形態での言語ツール108の構成と処理概要の例は図2と同じである。また、本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。
図4のステップ405の耐タンパコード挿入処理によって、チェックサム検証を行うことを可能とする命令列がどのように作成されるかを、簡単な例を挙げて説明する。図41は、C言語によりチェックサム検証を行うための指示を記述したソースプログラム106の例と、当該ソースプログラム106を本実施の形態でのコンパイラ201によってコンパイルした結果の例を表している。図中、斜字体で記載されている部分は、本実施の形態でのコンパイラ201の耐タンパコード挿入処理によって生成された命令列を表している。
ソースプログラム106の行4106〜行4107は、関数内における処理ブロックの例を表している。当該処理ブロックに対してチェックサム検証を行いたい場合、ユーザは実施の形態4と同様に、行4105および行4108の拡張言語仕様#pragmaにて、耐タンパコード挿入処理の対象範囲、すなわちチェックサム検証の対象範囲として当該処理ブロックを指定することができる。図42は、C言語でソースプログラム106を記述する場合の拡張言語仕様#pragmaによる書式の例である。書式4201の#pragmaを使用して、行4101において積算設定値を格納するレジスタのアドレスや、チェックサムの積算開始・終了を指示するためのレジスタおよびその設定値等を定義している。
本実施の形態でのコンパイラ201によるコンパイル結果では、行4117〜行4121までの処理範囲に対して積算設定値を算出して#CSというシンボルに定義し、行4112、行4113にてその値をレジスタに設定する命令列が生成されている。また、行4114、行4115および行4120、行4121にてハードウェアに対してチェックサムの積算開始の指示および積算終了と検証実行の指示を行うためのレジスタを設定する命令列が生成されている。
ここで処理中に条件分岐がある場合、条件分岐の後に続く命令列は、分岐条件により、実行されるか否かが実行時まで不明である。従って、ハードウェアによるチェックサム検証では、条件分岐命令の実行時に自動的にチェックサム検証が行われる場合がある。このとき、条件分岐をまたぐ範囲を耐タンパコード挿入処理の対象範囲、すなわちチェックサム検証の対象範囲として指定すると、チェックサムの検証時にエラーとなってしまう。
図43は、耐タンパコード挿入処理の対象範囲として条件分岐命令をまたぐ範囲を指定したソースプログラム106の例と、当該ソースプログラム106のコンパイル結果の例を表している。図中、斜字体で記載されている部分は、本実施の形態でのコンパイラ201の耐タンパコード挿入処理によって生成された命令列を表している。
ソースプログラム106の行4306〜行4307は、C言語による条件分岐処理の例を表しており、ここではif文を使用しているがfor文等でも同様である。この条件分岐処理全体を、行4305および行4308の#pragmaにて耐タンパコード挿入処理の対象範囲として指定している。この場合、プログラムの実行時に、コンパイル結果における行4319の条件分岐処理(BNE)においてハードウェアによって自動的にチェックサム検証が行われ、積算設定値算出の途中での検証となるために結果がエラーとなってしまう。
そこで、本実施の形態でのコンパイラ201では、処理中に条件分岐がある場合でもチェックサム検証が正しく行えるよう、耐タンパコード挿入処理の対象範囲として指定された範囲中に条件分岐が出現する毎に、対象範囲を区切ってチェックサム検証を行うように命令列を自動生成する。図44は、耐タンパコード挿入処理の対象範囲として条件分岐をまたぐ範囲を指定したソースプログラム106の例と、当該ソースプログラム106を本実施の形態でのコンパイラ201によってコンパイルした結果の例を表している。図中、斜字体で記載されている部分は、本実施の形態でのコンパイラ201の耐タンパコード挿入処理によって生成された命令列を表している。
図44のコンパイル結果において、行4419、行4428の分岐命令(BNE、BRA)の出現によって、積算の停止とその時点におけるチェックサム検証がハードウェアにより行われる。従って、そこまででチェックサム検証の対象範囲を区切り、そこから新たに積算を開始するための命令列が生成されている(行4421〜行4424、行4430〜行4433)。これにより、ユーザは条件分岐処理を意識することなく耐タンパコード挿入処理の対象範囲を指定することができ、容易にチェックサム検証を行うことが可能となる。
なお、本実施の形態での言語ツール108では、ソースプログラム106において耐タンパコード挿入処理の対象範囲、すなわちチェックサム検証の対象範囲を指定する方法として、図42に示す拡張言語仕様#pragmaにより処理ブロック毎に指定する方法をとっているが、実施の形態1と同様に、コンパイラ起動コマンドに付加するコンパイルオプションによって一括指定する方法をとることも可能である。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理によって挿入された中間語109については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
以上のように、本実施の形態での言語ツール108により、ハードウェアによって命令コードのチェックサム検証を行う際のハードウェアの設定や、チェックサム検証のための命令コードの積算開始・終了の指示、対象範囲の積算設定値の自動算出等を行うことによって、チェックサム検証によってプログラムの実行時の誤動作を検出または防止することを可能とする耐タンパ性を持つプログラムを生成することができる。また、このようなユーザが手作業で作成することが難しいプログラムを自動的に生成することができ、耐タンパ性を持つプログラムの開発生産性が向上する。また、本実施の形態での言語ツール108によってコンパイルを実行することにより、高級言語で記述された既存のソースプログラムをそのまま耐タンパ性を有するセキュアなプログラムへ移植することも容易となる。
<実施の形態7>
本発明の実施の形態7として、プログラムコードを二重化することによりプログラムの動作誤りを検出する例について説明する。
本発明の実施の形態7として、プログラムコードを二重化することによりプログラムの動作誤りを検出する例について説明する。
前述したように、暗号鍵を推定する誤動作解析アタック対策としては、暗号に応じて処理を二重化することにより2回計算を行い、2回の演算結果が等しくなることを確認する方法などが提案されている。この方法における2回計算は、プログラマーがその都度プログラミングをするか、2つ以上のCPUないし演算装置でそれぞれ計算し、計算結果の出力時にそれぞれが合致するかを確かめる方法で実現されてきており、プログラマーが新たにプログラムをするか、2回計算に適したハードウェアを用意する方法が主流であった。
二重化処理を用いることでプログラムの動作誤りを検出する方法で、特にプログラムの動作系を二重化するハードウェアの構成を用いず、既存の単一処理系を前提としたハードウェア上で実現する方法としては、実行されるプログラムを二重化することが合理的と考えられる。プログラムの二重化の対象としてはプログラムコードが考えられる。ここで、プログラムコードとは、プログラム言語で記述されたソースプログラムや、コンパイラを介して生成される中間語やアセンブリ言語プログラムや機械語である。
しかしながら、プログラムコードの二重化処理を用いることでプログラムの動作誤りを検出することは行われていない。それは、ソフトウェアの多重化自体が、プログラムの処理速度やメモリ使用効率の面で不利となることから、重要視されていなかったことに起因する。また、二重化処理を用いることでプログラムの動作誤りを検出する場合、二重化されたプログラムの実行後に一重目と二重目の計算結果の比較を行う必要があるが、一重目の演算中に演算処理で必要な変数が更新されることがあり、かかる場合には二重目の演算を正しく行うことができないから、結果として一重目と二重目の計算結果の比較が困難となることが考えられる。
そこで、本実施の形態では、プログラムコードを二重化した機械語の命令列を自動的に生成することにより、プログラムの動作誤りを検出する。プログラム動作誤り検出のための機能を追加する耐タンパコード挿入処理には、ソースプログラム中の予め指定された第1命令の二重化にかかる第2命令のコードを生成する第1機能と、前記第1命令の実行結果と、前記第2命令の実行結果とを比較するための比較処理のコードを生成する第2機能と、前記比較処理の結果が不一致とされた場合にプログラム実行を停止させるためのエラー処理コードを生成する第3機能とが含まれる。
さらに本実施の形態での耐タンパコード挿入処理には、前記第1命令の実行で用いられる変数と、その変数の他処理との関連を依存解析するためのコードを生成する第4機能と、前記第4機能の解析結果に基づいて、前記第2命令の実行に必要とされる変数を含む情報の複製を得るためのコードを生成する第5機能とが含まれる。そして前記依存処理では、後述する依存解析の深さを示す解析シンボルが用いられる。
以下に、本実施の形態での言語ツールの具体的な内容について説明する。本実施の形態での言語ツールが稼動する情報処理装置の例を示した構成図は図1と同じである。図45は、本実施の形態での言語ツール108の構成と処理概要の例を表した図である。図2で示した言語ツール108の構成に追加して、言語ツール108への入力として、ソースプログラム106とともに解析シンボル4501が入力されるようになっている。その他の構成は図2で示した構成と同じである。本実施の形態での言語ツール108が生成した実行可能プログラム107を動作させるターゲットマイコン208の例を示した構成図は図3と同じである。また、本実施の形態でのコンパイラ201での処理の流れの例は図4と同じである。
図4のステップ405の耐タンパコード挿入処理によって、プログラムコードの二重化がどのように行われるかを、簡単な例を挙げて説明する。図46は、一般的なソースプログラム106での処理の流れの例を表した図である。プログラムコードは、少なくとも制御フローにおける命令処理単位を境界として分割した単位であるので、スタート(Start)4601と命令処理(1)4602が分割の1つであるプログラムコード(1)4611とされ、命令処理(2)4603と命令処理(3)4604とが分割の1つであるプログラムコード(2)4621とされ、命令処理(4)4605とエンド(End)4606とが分割の1つであるプログラムコード(3)4631とされる。
図47は、図46のソースプログラム106を入力として本実施の形態での言語ツール108によって得られた実行可能プログラム107での処理の流れの例を表した図である。図47の例では、ユーザにより二重化を行う対象として指定されたプログラムコード(2)4621が二重化処理されている。すなわち、命令処理(2)4603及び命令処理(3)4604が二重化され、二重命令処理(1)4702及び二重命令処理(2)4703が挿入されている。
また、プログラムコード(2)4621において、命令処理(2)4603の前に変数コピー処理4701が挿入される。変数コピー処理4701では、命令処理(2)4603で用いられる変数と、命令処理(3)4604で用いられる変数とが、互いに異なる記憶領域にコピーされる。例えば命令処理(2)4603で用いられる変数が第1記憶領域にコピーされ、命令処理(3)4604で用いられる変数が第2記憶領域にコピーされる。このような変数コピー処理4701により変数の複製が得られる。さらに、この変数コピー処理4701において、命令処理(2)4603と、命令処理(3)4604とで書き換わる変数があるか否かを命令処理の記述から判定し、書き換わる変数にはフラグが立てられる。
そして、前記変数コピー処理4701の後に、命令処理(2)4603と、命令処理(3)4604とが挿入される。その後、命令処理(2)4603と論理的にもしくは数学的に同値となる二重命令処理(1)4702が挿入され、さらに、命令処理(3)4604と論理的にもしくは数学的に同値となる二重命令処理(2)4703が挿入される。二重命令処理(1)4702では、前記第1記憶領域にコピーされた変数が参照され、二重命令処理(2)4703では、前記第2記憶領域にコピーされた変数が用いられる。
前記二重命令処理(2)4703の後に比較処理4604が挿入される。この比較処理4704では、前記フラグが立てられた変数が、命令処理(2)4603と、二重命令処理(1)4702の実行や、命令処理(3)4604と、二重命令処理(2)4703の実行により、書き換わったか否かの判別が行われる。そして、前記比較処理4704において、前記フラグが立てられた変数が一つでも書き換えられていると判断された場合には、プログラム実行停止のためのエラー処理4705に遷移する。前記比較処理4704において、変数の書き換えが行われていないと判断された場合には、プログラムコード(3)4631の命令処理(4)4605に遷移するようになっている。
前記の例によれば、命令処理(2)4603もしくは命令処理(3)4604の処理中にハードウェア誤動作が発生し、記憶領域のデータが予想しない値に変化されるか、あるいは処理そのものを誤ったとしても、二重命令処理(1)4702もしくは二重命令処理(2)4703の実行により、それぞれ同値となる処理が行われることから、二重命令処理(1)4702もしくは二重命令処理(2)4703の実行で同一のハードウェア誤動作が起きない限り、比較処理4704において、プログラムの動作誤りを検知することができる。
次に、前記二重化処理についてさらに詳細に説明する。図48は、前記二重化処理についての具体例を示した図である。プログラムコード4821、4831、4841を含むソースプログラム106が言語ツール108に入力され、プログラムコード4831についての二重化処理が指定された場合には、プログラムコード4811において、命令処理4802の前に変数コピー処理4801が挿入される。
ここでは、変数f、e、gの複製f'、e'、g'が得られる。命令処理4802で用いられる変数e、f、gの複製e'、f'、g'が第1記憶領域にコピーされ、命令処理4803で用いられる変数g、e、fの複製g'、e'、f'が第2記憶領域にコピーされる。命令処理4802の二重化にかかる二重化命令処理4804により、「e'=f'*g'」の演算処理が行われ、命令処理4803の二重化にかかる二重化命令処理4805により、「g'=e'+f'」の演算処理が行われる。
比較処理4806では、変数e、f、gと、その複製e'、f'、g'との比較が行われる。この比較結果に基づいて、全ての変数が一致しない限り、プログラム実行停止のためのエラー処理4807に遷移する。
なお、プログラムコード4831に対して二重化処理を行うためのユーザの指示は、例えば、実施の形態1での言語ツール108のように、拡張言語仕様#pragmaを用いて指定する方法や、コンパイラ201に対するコンパイラオプションによって指定する方法などを用いることができる。
また、実施の形態1と同様に、図4のステップ407の最適化処理では、耐タンパコード挿入処理によって挿入された命令についての中間語109については、冗長な命令であるとして削除したり変形したりしないようにし、挿入された耐タンパコードが最適化処理においても保存されるようにする。
ソースプログラム106において処理の実行に用いられる変数と、その変数の他処理との関連を解析する前記依存解析の深さは、ソースプログラム106とともに言語ツール108に入力される解析シンボル4501によって指定することができる。
例えば図49に示されるように、対象となるソースプログラム106が命令処理4902〜4908を含む場合を考える。かかる場合において、変数Gについて浅い依存解析4909が指定された場合には、依存範囲4910が変数E、Fのみに限定される。それに対して、変数Gについて深い依存解析4911が指定された場合には、依存範囲4912が変数A、B、C、D、E、Fにまで拡げられる。依存解析の深さが深いほど解析精度は向上するが、情報量が多くなるため解析に時間がかかる。依存解析の深さは、対象となるソースプログラム106に応じて適宜指定するのが望ましい。
以上のように、本実施の形態によれば、以下の作用効果を得ることができる。
(1)言語ツール108を実行する情報処理装置により生成された実行可能プログラム107を実行するターゲットマイコン208によれば、二重化処理を行うプログラムコードの実行直前において、プログラムコードがアクセスする記憶領域中の変数が記憶領域中の別領域に二重化される。特に、プログラムコード中の変数の依存解析を行うことで、効率的な変数の二重化が実現可能である。この二重化された変数を用いて、二重化対象となるプログラムコードで一重目のプログラムコードによる計算が行われ、二重目のプログラムコードでは二重化を行った変数を用いて二重目の計算が行われる。一重目の計算で変数の値や情報が更新されていたとしても、二重目の処理で用いる変数は一重目の計算を行う前に別領域に二重化されたものであることから、一重目の計算による更新に影響されない。この結果、一重目と二重目の処理ではそれぞれ同一の計算処理が行うことができる。これらを踏まえて一重目と二重目の計算を順次実行した後に、一重目と二重目の計算によって更新された変数を比較することで、計算処理中に起きた誤動作の検知を容易に行うことができる。
(2)前記(1)の作用効果を発揮する実行可能プログラム107は、言語ツール108を実行する情報処理装置でのコンパイル処理において自動的に生成されるため、ソースプログラム106に対する二重化処理をプログラマーが行わずに済む。
(3)図47における変数コピー処理4701において、命令処理(2)4603と、命令処理(3)4604とで書き換わる変数があるか否かが命令処理の記述から判定され、書き換わる変数にはフラグが立てられる。そして、比較処理4704では、前記フラグが立てられた変数が、命令処理(2)4603と、二重命令処理(1)4702の実行や、命令処理(3)4604と、二重命令処理(2)4703の実行により、書き換わったか否かの判別が行われる。このように比較処理4704において前記フラグが立てられた変数のみが比較対象とされるので、全ての変数について比較処理を行う場合に比べて、必要な処理を短時間で完了することができる。
<実施の形態8>
本発明の実施の形態8として、プログラムコードを二重化することによりプログラムの動作誤りを検出する別の構成例について説明する。
本発明の実施の形態8として、プログラムコードを二重化することによりプログラムの動作誤りを検出する別の構成例について説明する。
図50に示されるターゲットマイコン5000は、特に制限されないが、ICカード310に搭載されるICカード用マイコンとされ、特に制限されないが、記憶装置5005、命令解釈実行装置5007、二重化データ用記憶装置5008、および演算器5009を含み、それらがバス5006により、相互に信号のやり取りが可能に結合される。そして、ターゲットマイコン5000は、特に制限されないが、公知の半導体集積回路製造技術により、単結晶シリコン基板などの一つの半導体基板に形成される。
前記記憶装置5005には、データ領域(1)5001、データ領域(2)5002、命令列領域5003、二重化処理命令列領域5004が形成される。プログラム動作誤りを検出したい命令列は、記憶装置5005内の命令列領域5003に格納されている。命令列領域5003の命令列の一部には、プログラム動作誤り検出を行いたい命令であることを示すマークが付されている。このマークがトリガとなって命令の二重化処理が行われる。
命令解釈実行装置5007は、いわゆるCPUとされ、バス5006を介して、命令列領域5003の命令を順次フェッチし、それを解釈して実行する。この命令実行結果は、データ領域(1)5001に格納される。このとき、データ領域(1)5001は結果を格納するだけでなく、命令解釈実行装置5007がデータを参照する為に使われることもある。
プログラム動作誤り検出を行いたい命令であることを示すマークが付された命令がフェッチされた場合、当該命令を実行する前に、二重化処理命令列領域5004の二重化処理命令列の実行に遷移される。命令解釈実行装置5007は、前記二重化処理命令列に従い、二重化対象となる命令を命令列領域5003から読み出し、当該命令実行において用いられる、データ領域(1)5001内のデータをデータ領域(2)5002にコピーし、その後に、プログラム動作誤り検出を行いたい命令であることを示すマークが付された命令(先にフェッチした命令)を実行する。このとき、命令解釈実行装置5007は、データ領域(1)5001のデータを参照することもある。
プログラム動作誤り検出を行いたい命令であることを示すマークが付された命令の実行結果は、二重化データ用記憶装置5008に書き込まれる。その後に、命令解釈実行装置5007は、前記マークが付された命令と同一命令若しくはそれと等価な命令を実行する。結果的に前記マークが付された命令が複数回実行される。このとき、命令解釈実行装置5007は、参照すべきデータがある場合には、データ領域(1)5001ではなく、必ずデータ領域(2)5002を参照する。そして前記マークが付された命令と同様の命令の実行結果は、二重化データ用記憶装置5008における未使用領域に書き込まれる。
その後、命令解釈実行装置5007は、演算器5009の動作を制御して、二重化データ用記憶装置5008内の2つの命令実行結果を比較する。この結果が一致しない場合、演算器5009は、制御信号Signal5010をアサートする。これにより、命令解釈実行装置5007は、プログラム実行を停止させるためのエラー処理に遷移され、そのエラー処理が行われることで、それ以降のプログラム実行が停止される。また、二重化データ用記憶装置5008内の2つの命令実行結果が一致する場合には、命令列領域5003から次の命令がフェッチされる。そして、前記マークが付されていない命令がフェッチされた場合には、命令解釈実行装置5007による前記二重化処理は行われない。
前記の構成によれば、命令列領域5003の命令列において、プログラム動作誤り検出を行いたい命令であることを示すマークが付されていれば良いので、命令列領域5003の命令列は、図45〜図49に示した場合のように、言語ツール108において、プログラム動作誤り検出のための機能をソースプログラム106や中間語109などに追加する処理が不要とされる。換言すれば、既存の実行可能プログラム107の命令列に対してマークを付することによって、再コンパイルなどをしなくても、プログラムコードの二重化処理を用いることでプログラムの動作誤りを検出することができる。
さらに、例えば、図50に示される構成では、命令列領域5003の命令列の一部には、プログラム動作誤り検出を行いたい命令であることを示すマークが付され、このマークがトリガとなって命令の二重化処理が行われるようにしたが、記憶装置5005内に二重化処理タイミングを決定するためのデータを格納しておき、このデータに基づいて、対応するタイミングで二重化処理を行うようにしても良い。かかる場合には、命令列領域5003の命令列の一部にプログラム動作誤り検出を行いたい命令であることを示すマークを付する必要が無い。
以上に説明した各実施の形態において、前記ターゲットマイコン208、5000は、ICカード以外にも適用することができる。また、言語ツール108における耐タンパコード挿入処理は、図20で示した例のように、それぞれを任意に組み合わせて用いることも可能である。
また、以上の説明では、主として本発明者によってなされた発明をその背景となった利用分野であるコンパイラ201を有する言語ツール108に適用した場合について説明したが、本発明はそれに限定されるものではない。少なくともソースプログラム106を実行可能プログラム107に変換することを条件に適用することができ、ソースプログラム106を実行可能プログラム107に変換するための処理をコンピュータによって実現するための形式変換プログラムに広く適用することができる。
以上、本発明者によってなされた発明を実施の形態に基づき具体的に説明したが、本発明は前記実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で種々変更可能であることはいうまでもない。
本発明のプログラム作成方法は、ICカード等の情報処理装置や組込みシステムに搭載する耐タンパ性を持つセキュアなプログラムの作成方法に利用可能である。また当該プログラムを搭載するICカード等のセキュリティ用途向けのマイコンなどにも利用可能である。
101…CPU、102…ディスプレイ、103…入出力デバイス、104…主記憶装置、105…外部記憶装置、106…ソースプログラム、107…実行可能プログラム、108…言語ツール、109…中間語、
201…コンパイラ、202…フロントエンド、203…バックエンド、204…アセンブラ、205…リンケージエディタ、206…アセンブリ言語プログラム、207…機械語プログラム、208…ターゲットマイコン、
301…不揮発性メモリ、302…プログラム格納領域、303…データ格納領域、304…揮発性メモリ、305…入出力部、306…コプロセッサ、307…CPU、308…暗号専用回路、309…バス、310…ICカード、311…外部端子、
4501…解析シンボル、
5000…ターゲットマイコン、5001…データ領域(1)、5002…データ領域(2)、5003…命令列領域、5004…二重化処理命令列領域、5005…記憶装置、5006…バス、5007…命令解釈実行装置、5008…二重化データ用記憶装置、5009…演算器、5010…制御信号Signal。
201…コンパイラ、202…フロントエンド、203…バックエンド、204…アセンブラ、205…リンケージエディタ、206…アセンブリ言語プログラム、207…機械語プログラム、208…ターゲットマイコン、
301…不揮発性メモリ、302…プログラム格納領域、303…データ格納領域、304…揮発性メモリ、305…入出力部、306…コプロセッサ、307…CPU、308…暗号専用回路、309…バス、310…ICカード、311…外部端子、
4501…解析シンボル、
5000…ターゲットマイコン、5001…データ領域(1)、5002…データ領域(2)、5003…命令列領域、5004…二重化処理命令列領域、5005…記憶装置、5006…バス、5007…命令解釈実行装置、5008…二重化データ用記憶装置、5009…演算器、5010…制御信号Signal。
Claims (16)
- コンピュータにより、プログラミング言語で記述されたソースプログラムを読み込んで実行可能プログラムを生成するプログラム作成方法であって、
前記コンピュータは、前記ソースプログラムを読み込んで構文解析を行う構文解析ステップと、該ソースプログラムから中間語の生成を行う中間語生成ステップと、該中間語に対してレジスタを割り付けるレジスタ割り付けステップと、該中間語に対して最適化処理を行う最適化処理ステップと、該中間語からアセンブリ言語プログラムを生成するアセンブリ言語生成ステップと、該アセンブリ言語プログラムから機械語プログラムを生成する機械語生成ステップと、該機械語プログラムと他の機械語プログラムとを結合させて実行可能プログラムを生成する機械語プログラム結合ステップとを実行し、
前記ソースプログラムを読み込んでから前記実行可能プログラムを生成するまでの間で、ユーザの指示に基づいて、前記ソースプログラムもしくは前記中間語もしくは前記アセンブリ言語プログラムもしくは前記機械語プログラムに対して、前記実行可能プログラムの動作内容の不正な解析に対抗する耐タンパ性を有するコードを自動的に生成する耐タンパコード挿入ステップを実行することを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中の多重条件分岐処理に対して、各条件分岐の判定処理を正しく通過してきたかどうかをチェックするための情報をレジスタ又はメモリ上に保持し、各条件分岐先の処理内で前記情報が妥当な値であるかどうかをチェックすることにより、前記実行可能プログラムの実行時の誤動作を検出または防止することを可能とするコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中の条件分岐処理に対して、該条件分岐での判定処理を二重もしくはそれ以上に多重化することにより、前記実行可能プログラムの実行時の誤動作を検出または防止することを可能とするコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中の関数呼び出し処理に対して、関数呼び出し側では、呼び出し先の関数へ渡す引数から予め定められた手順により計算されるチェック用の値をレジスタ又はメモリ上に設定しておき、呼び出された関数側では、渡された引数から予め定められた手順により計算される値と、前記チェック用の値とを比較して引数の妥当性をチェックすることにより、前記実行可能プログラムの実行時の誤動作を検出または防止することを可能とするコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中のループ処理に対して、同一の処理内容である複数パターンの命令列を生成することにより、前記実行可能プログラムの実行時の電流特性の特徴を希薄化するコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中の条件分岐処理に対して、各条件分岐経路の実行時間を均一化する命令列を生成することにより、前記実行可能プログラムの実行時の電流特性の特徴を希薄化するコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップで生成する耐タンパ性を有するコードは、前記ソースプログラム中のユーザにより指示された処理範囲に対して、該処理範囲の命令コードを積算したチェックサムの期待値を算出し、チェックサムによる検証を行うためのハードウェアの設定、命令コードの積算の開始・終了およびチェックサムによる検証の実行をハードウェアに指示する命令列を生成することにより、前記実行可能プログラムの実行時の誤動作を検出または防止することを可能とするコードであることを特徴とするプログラム作成方法。 - 請求項1記載のプログラム作成方法において、
前記耐タンパコード挿入ステップでは、プログラム動作誤り検出のためのコードとして、前記ソースプログラム中の予め指定された第1命令の二重化にかかる第2命令のコードと、前記第1命令の実行結果と、前記第2命令の実行結果とを比較するための比較処理のコードと、前記比較処理の結果が不一致とされた場合に所定のエラー処理を行うためのコードとを生成することを特徴とするプログラム作成方法。 - 請求項8記載のプログラム作成方法において、
前記耐タンパコード挿入ステップでは、さらに、前記第1命令の実行で用いられる変数と該変数の他処理との関連を依存解析するためのコードと、前記依存解析の結果に基づいて、前記第2命令の実行に必要とされる変数を含む情報の複製を得るためのコードと、前記変数を含む情報の複製を用いて前記第2命令を実行するコードとを生成することを特徴とするプログラム作成方法。 - 請求項9記載のプログラム作成方法において、
ユーザにより前記依存解析の深さの指定が可能であることを特徴とするプログラム作成方法。 - プログラミング言語で記述されたソースプログラムを実行可能プログラムに変換する第1処理と、前記ソースプログラムを前記実行可能プログラムに変換する前に、プログラム動作誤り検出のための機能を追加する第2処理と、を実行可能なCPUを含む情報処理装置であって、
前記第2処理では、前記ソースプログラム中の予め指定された第1命令の二重化にかかる第2命令のコードと、前記第1命令の実行結果と、前記第2命令の実行結果とを比較するための比較処理のコードと、前記比較処理の結果が不一致とされた場合に所定のエラー処理を行うためのコードとを生成することを特徴とする情報処理装置。 - 請求項11記載の情報処理装置において、
前記第2処理では、さらに、前記第1命令の実行で用いられる変数と、該変数の他処理との関連を依存解析するためのコードと、前記依存解析の結果に基づいて、前記第2命令の実行に必要とされる変数を含む情報の複製を得るためのコードと、前記変数を含む情報の複製を用いて前記第2命令を実行するコードとを生成することを特徴とする情報処理装置。 - 請求項12記載の情報処理装置において、
ユーザにより前記依存解析の深さの指定が可能であることを特徴とする情報処理装置。 - プログラムを解釈して実行可能な命令解釈実行装置を有するマイコンであって、
前記プログラムに含まれる所定命令について前記命令解釈実行装置で複数回実行された結果が書き込まれる二重化データ用記憶装置と、前記二重化データ用記憶装置内のデータに基づいて、前記命令解釈実行装置で複数回実行された結果の比較を行い、その比較結果が不一致とされた場合に、前記命令解釈実行装置の動作を停止させるための信号を生成する演算器とを有することを特徴とするマイコン。 - 請求項14記載のマイコンにおいて、
前記プログラムに含まれる所定命令について前記命令解釈実行装置で複数回実行されるときに用いられる変数は、前記所定命令が前記命令解釈実行装置で実行される前に複製されることを特徴とするマイコン。 - 実行可能プログラムおよび暗号鍵データや機密情報が格納されたメモリと、前記実行可能プログラムを解釈して実行可能なCPUと、外部との入出力を制御する入出力部と、これらを接続するバスとを有し、
前記メモリに格納されている前記機密情報を不正に参照・書き換えされないように、前記暗号鍵データを用いた暗復号処理によって前記機密情報のやり取りを行うマイコンであって、
前記メモリに格納された前記実行可能プログラムは、請求項1記載のプログラム作成方法により生成された実行可能プログラムであることを特徴とするマイコン。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2007231299A JP2009009537A (ja) | 2006-09-11 | 2007-09-06 | プログラム作成方法及び情報処理装置ならびにマイコン |
US11/853,058 US20080271001A1 (en) | 2006-09-11 | 2007-09-11 | Method of generating program, information processing device and microcomputer |
Applications Claiming Priority (4)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2006245821 | 2006-09-11 | ||
JP2007027989 | 2007-02-07 | ||
JP2007144454 | 2007-05-31 | ||
JP2007231299A JP2009009537A (ja) | 2006-09-11 | 2007-09-06 | プログラム作成方法及び情報処理装置ならびにマイコン |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2009009537A true JP2009009537A (ja) | 2009-01-15 |
Family
ID=40324516
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2007231299A Withdrawn JP2009009537A (ja) | 2006-09-11 | 2007-09-06 | プログラム作成方法及び情報処理装置ならびにマイコン |
Country Status (1)
Country | Link |
---|---|
JP (1) | JP2009009537A (ja) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2010198147A (ja) * | 2009-02-24 | 2010-09-09 | Mitsubishi Heavy Ind Ltd | コンピュータメモリにおけるスタック領域のデータの保護方法 |
JP2013524322A (ja) * | 2010-03-31 | 2013-06-17 | イルデト カナダ コーポレーション | カプセル化し、ソフトウェアライブラリ中の多様化によって保護を可能にするための、システムと方法 |
WO2018220836A1 (ja) * | 2017-06-02 | 2018-12-06 | 三菱電機株式会社 | プログラムコード生成装置およびプログラムコード生成プログラム |
WO2021117524A1 (ja) * | 2019-12-10 | 2021-06-17 | 株式会社日立製作所 | 実行ファイル生成装置、方法、およびプログラムが記録された非一時的記憶媒体 |
-
2007
- 2007-09-06 JP JP2007231299A patent/JP2009009537A/ja not_active Withdrawn
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2010198147A (ja) * | 2009-02-24 | 2010-09-09 | Mitsubishi Heavy Ind Ltd | コンピュータメモリにおけるスタック領域のデータの保護方法 |
JP2013524322A (ja) * | 2010-03-31 | 2013-06-17 | イルデト カナダ コーポレーション | カプセル化し、ソフトウェアライブラリ中の多様化によって保護を可能にするための、システムと方法 |
US10185837B2 (en) | 2010-03-31 | 2019-01-22 | Irdeto B.V. | System and method for encapsulating and enabling protection through diverse variations in software libraries |
WO2018220836A1 (ja) * | 2017-06-02 | 2018-12-06 | 三菱電機株式会社 | プログラムコード生成装置およびプログラムコード生成プログラム |
WO2021117524A1 (ja) * | 2019-12-10 | 2021-06-17 | 株式会社日立製作所 | 実行ファイル生成装置、方法、およびプログラムが記録された非一時的記憶媒体 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US20080271001A1 (en) | Method of generating program, information processing device and microcomputer | |
US7757097B2 (en) | Method and system for tamperproofing software | |
US8434059B2 (en) | Systems, methods, and computer-readable media for fertilizing machine-executable code | |
JP4777903B2 (ja) | 実行トレースプリントを検証することによるプログラム実行整合性の制御方法 | |
Moss et al. | Compiler assisted masking | |
US7287166B1 (en) | Guards for application in software tamperproofing | |
JP4849606B2 (ja) | 制御フロー誤り検出方法、データ処理装置、及びコンパイラ | |
JP5460699B2 (ja) | ソフトウェアアプリケーションのホワイトボックス実装を生成するためのシステムおよび方法 | |
US7254586B2 (en) | Secure and opaque type library providing secure data protection of variables | |
US7111285B2 (en) | Method and system for protecting software applications against static and dynamic software piracy techniques | |
JP5643894B2 (ja) | サイドチャネル攻撃および反復起動攻撃に耐える動的可変タイミング演算パスのシステムおよび方法 | |
US8176473B2 (en) | Transformations for software obfuscation and individualization | |
JP5467271B2 (ja) | 情報処理装置及びプログラム、情報処理方法、記録媒体 | |
JP7154365B2 (ja) | ソフトウェアコードをセキュアにするための方法 | |
US9721120B2 (en) | Preventing unauthorized calls to a protected function | |
BRPI0614089A2 (pt) | método para evitar engenharia reversa de software, modificação não autorizada e interceptação de dados de tempo de execução | |
JP2021515314A (ja) | コンパイルデバイス及び方法 | |
JP7242675B2 (ja) | コンパイル装置及び方法 | |
Shivakumar et al. | Typing high-speed cryptography against spectre v1 | |
CN112434266A (zh) | 一种shellcode控制流扁平化混淆方法 | |
US8302210B2 (en) | System and method for call path enforcement | |
US9639673B2 (en) | Protecting software through a fake cryptographic layer | |
JP2009009537A (ja) | プログラム作成方法及び情報処理装置ならびにマイコン | |
JP4754635B2 (ja) | 制御フロー保護機構 | |
US8423974B2 (en) | System and method for call replacement |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A621 | Written request for application examination |
Free format text: JAPANESE INTERMEDIATE CODE: A621 Effective date: 20100215 |
|
A711 | Notification of change in applicant |
Free format text: JAPANESE INTERMEDIATE CODE: A712 Effective date: 20100528 |
|
A761 | Written withdrawal of application |
Free format text: JAPANESE INTERMEDIATE CODE: A761 Effective date: 20111017 |