JP4754635B2 - 制御フロー保護機構 - Google Patents

制御フロー保護機構 Download PDF

Info

Publication number
JP4754635B2
JP4754635B2 JP2008535832A JP2008535832A JP4754635B2 JP 4754635 B2 JP4754635 B2 JP 4754635B2 JP 2008535832 A JP2008535832 A JP 2008535832A JP 2008535832 A JP2008535832 A JP 2008535832A JP 4754635 B2 JP4754635 B2 JP 4754635B2
Authority
JP
Japan
Prior art keywords
value
area
execution
program
region
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.)
Expired - Fee Related
Application number
JP2008535832A
Other languages
English (en)
Other versions
JP2009525509A (ja
Inventor
ケイ アンドリュー
カービィ アンソニー
ノンウィラー ジョン
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Sharp Corp
Original Assignee
Sharp Corp
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Sharp Corp filed Critical Sharp Corp
Publication of JP2009525509A publication Critical patent/JP2009525509A/ja
Application granted granted Critical
Publication of JP4754635B2 publication Critical patent/JP4754635B2/ja
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/07Responding to the occurrence of a fault, e.g. fault tolerance
    • G06F11/14Error detection or correction of the data by redundancy in operation
    • G06F11/1402Saving, restoring, recovering or retrying
    • G06F11/1405Saving, restoring, recovering or retrying at machine instruction level
    • G06F11/1407Checkpointing the instruction stream
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/28Error detection; Error correction; Monitoring by checking the correct order of processing

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Computer Security & Cryptography (AREA)
  • Software Systems (AREA)
  • Quality & Reliability (AREA)
  • Computer Hardware Design (AREA)
  • Storage Device Security (AREA)
  • Debugging And Monitoring (AREA)
  • Executing Machine-Instructions (AREA)

Description

発明の詳細な説明
〔技術分野〕
本発明は、演算装置のための制御フロー保護機構に関する。
〔背景技術〕
CPUベースのデバイスは、記憶されたプログラムおよび記憶されたデータを用いて、その入力において動作し、出力を生成する。プログラムは、個別の命令から構成されている。これら個別の命令は、プログラマーが設計したプログラムロジックによって決定される順序で、CPUによって実行される。CPUは、フェッチまたは実行される次の命令が記憶されているアドレスを示す、プログラムカウンタ(PC)の概念を有している。プログラムカウンタは、ハードウェアレジスタと同一であると見なされる場合があるが、他の態様も存在する。命令が実行されると、プログラムカウンタは、次の命令を示すようにCPUによって更新される。次の命令は、通常、(単純な命令または「非分岐」命令の場合は、)記憶されている前の命令の真上のメモリ領域に位置しており、あるいは、「分岐」ジャンプまたはコール型の命令の場合は専ら、別の場所に位置している。このモデルでは、割り込みは無視される。
セキュリティデバイス上で実行されるソフトウェアは、様々な種類の攻撃から保護されなければならない。このような攻撃の種類の1つとして、「故障利用」攻撃が挙げられる。故障利用攻撃は、通常ではない方法でデバイスを操作して誤動作させ、その誤動作によって、攻撃者の意図する影響をデバイスに及ぼさせるものである。故障利用攻撃の種類の1つとして、攻撃者は、電源またはI/Oポートに一時的な電圧スパイク(すなわち「グリッチ」)を生じさせ、あるいはCPU ICに明るい閃光を与える。これによって、(他の効果の中でもとりわけ、)プログラムカウンタが予期しないアドレスへ変更され、コード実行はそのアドレスから続けられる。従って、プログラマーの予期せぬ順序でプログラムが実行される。攻撃者は、デバイスに機密情報を露呈させるために適したグリッチを見つけ出す、あるいは、セキュリティ検査を巧みに回避するなどを辛抱強く行う。これらが機能するとは考えにくいが、事実上の現実的な攻撃技術である。
例えば、プログラマーは、関数“make_credit()”を与える。これは、セキュリティ検査(例えば、PIN検査およびパラメータ検査)を通過した後にのみコールされる関数である。攻撃者は、プログラムカウンタをコード内の別の場所からmake_credit()へジャンプさせることができた場合、PIN検査を受けることなくcreditを加えることができる。同様の別の攻撃では、機密内部データが、デバイスの出力チャネルに誤ってコピーされる場合がある。このように一旦デバイス情報が漏洩すると、その攻撃パラメータを用いて他の同様のデバイス(あるいは、別の機会に同一のデバイス)への攻撃を複製することも可能となる。
同様の考えは、例えば宇宙線あるいは他の偶発的な事象(デバイス部品の不具合など)によってもたらされる、不注意によるプログラムカウンタの一時的変更にも当てはまる。セキュリティシステムだけではなく、セーフティクリティカルおよびミッションクリティカルなシステムもまた危険に曝されている。
予期せぬメモリ領域にプログラム実行をジャンプさせる、上述した全ての種類のグリッチ、およびデバイスに影響を及ぼす他の物理的要因(例えばデバイス不具合)を、ここでは一般的に「物理的妨害」と称する。
US5,274,817(キャタピラー社)は、サブルーチンコールを実行する方法を開示している。当該方法では、サブルーチンコールに、検査アドレスがスタックに記憶される。サブルーチンコールは、サブルーチンが、コールしたルーチンに戻る前に確認される。これによって、プログラムカウンタ値に誤りを生じさせる偶発的な妨害に対して、ある程度の保護を加えることができる。しかし、開示されている当該方法は、不正確な関数のコールを防止していない場合がある。例えば、保護されたコールを意図する関数にセットアップするスタックプッシュ演算(stack push operation)の直前から、保護されたコールを意図せぬ関数にセットアップするスタックプッシュ演算の直前に実行がジャンプした場合、呼び出された(意図せぬ)関数において誤りが認識されない。
JP4111138(富士通)は、ハードウェア検出システムに依存して、プログラムカウンタにおいてどのような遷移が許容されるのかを示す、世界モデルの使用を開示している。
EP0590866(AT&T)は、故障検出ではなく、フォールトトレランスを提供する演算技術を開示している。
US5,758,060(ダラスセミコンダクタ)は、ソフトウェアが所定量のコードを省略していないことを実証するための、ハードウェアを開示している。当該技術は、ハードウェアタイマーを検査して、所定のデータ演算がほぼ適切なタイミングで行われるかどうか否かを判別する工程を含んでいる。
GB1422603(エリクソン)は、故障を検出するためにコードの各セクションを実行するのに要した時間を検査する技術を開示している。
US6,044,458(モトローラ)は、オペコード(opcodes)に順番に記憶された固定語(fixwords)を用いてプログラムフローを監視するハードウェア技術を開示している。
US5,717,849(IBM)は、連鎖的な一連の制御ブロックにおいて故障を早期検出するシステムおよび手順を開示している。プログラム実行における各作業の単位(すなわち「ブロック」)が、適切なプログラムに正確に関連付けられているかを検査する(これによって、関係のないブロックが実行されることがない)方法が開示されている。これは、ブロックが、オペレーティングシステムによって(例えばリモート記憶装置から)、プログラム実行の一部としてではなく負荷されたときに、(ブロック内にデータとして埋め込まれている)タグを比較することによって行われる。当該方法による保護は、本発明に係る保護に対して相補的である。
従来技術では、「ウォオッチドッグ」タイマーの使用は周知である。ウォッチドッグは、プログラムによって間隔を置いてリセットされるハードウェアデバイスである。ウォッチドッグは、(例えば攻撃中に)プログラムが不具合を起こして、タイマーを迅速にリセットしない場合にタイムアウトするため、適切な処置を講じることができる。しかし、特殊なハードウェアが必要であり、また検出がやや粗雑であるため、いかなるリセットポイントに達するソフトウェアによっても、ウォッチドッグの機能が弱められる。
プログラムは、グリッチが生じたか否かをCPUクロック(サイクルカウンタ)を用いて判別することができると考えられている。グリッチ後、グリッチ前に期待されたよりも速く(または遅く)動作が完了する場合がある。しかしこのような方法は、一般的には、完了するまでの長さがデータ依存的または環境依存的であるコードの検査には不適当である。
今日まで考えられた別の方法では、プログラム実行状態の可能な進展の実行可能モデルが提供される。プログラムは、実行時に、その状態に関する情報をモデル部品に与える。達するべきではない状態にプログラムが達したことをモデルが判別すると、攻撃が行われていると見なされて、処置を講じることができる。しかし、このようなモデルは、開発コストが高い場合があり、また不正確である(許容度が過度に高い)か、あるいは大型で非効率である可能性がある。
〔発明の開示〕
本発明の第1の形態によると、複数の領域を通る実行パスに従ってデバイス上において実行されるプログラムを、予期しないメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクなどの物理的妨害によって生じる実行フローエラーから、少なくともある程度は保護する方法であって、ランダムにアクセス可能なメモリ領域に第1の検査値を提供する工程と、少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否かを判別する工程と、第1の領域から、上記のような判別が成される第2の領域へと実行が通過するときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する工程と、上記のような判別が否定的であった場合にエラー処理手順を行う工程とを含んでいる、方法が提供される。
上記方法は、上記のような判別工程を、クリティカルな性質(critical nature)を有する上記プログラムの少なくとも一部の演算の前に行う工程を含んでいてもよい。
上記方法は、上記のような判別工程を、上記検査値更新工程の少なくとも一部の前に行う工程を含んでいてもよい。
上記方法は、上記のような判別工程を、上記デバイスの持続ストレージを更新する上記プログラムの少なくとも一部の演算の前に行う工程を含んでいてもよい。
上記方法は、上記のような判別工程を、上記デバイスの外側または上記デバイスの保護領域の外側にデータを送信させる少なくとも一部の演算の前に行う工程を含んでいてもよい。
上記方法は、ランダムにアクセス可能なメモリ領域に第2の検査値を設ける工程と、領域が、コール領域からコールされるコードの機能ユニットを有している場合は、リターン領域に実行を戻す工程と、実行が上記機能ユニット外に進む前に、上記機能ユニットに対して予想される最終値を有するように、第2の検査値を更新する工程と、実行が上記機能ユニット外に進んだ後および実行が上記リターン領域に戻る前に、上記第2の検査値が上記予想された最終値を有しているか否かを判別する工程とを含んでいてもよい。
上記リターン領域は、上記コール領域と同一であってもよい。
上記第2の検査値は、同一のランダムにアクセス可能なメモリ領域を用いて、上記第1の検査値と同一であってよく、上記第2の領域において予想される上記値を有するように上記第1の検査値が更新される前に、上記第2の検査値が、上記予想される最終値を有しているか否かを判別する工程を含んでいてもよい。
上記方法は、上記第2の領域に実行が進む前に、上記更新工程が行われる上記第1の領域に実行が入るときに、上記第1の領域において予想される値を有するように上記第1の検査値を更新する工程を含んでいてもよい。
上記方法は、上記検査値が予想外の値を一旦推定すると、後に行われる上記のような更新においても期待外の値を保持する可能性を有するように、上記検査値を更新する工程を含んでいてもよい。
上記方法は、上記更新された検査値が上記更新前に上記第1の領域に対する上記予想値を有している場合に限り、上記更新された検査値が上記第2の領域に対する上記予想値を有するように、上記検査値を、上記第2の領域に対するその予想値および上記第1の領域に対するその予想値に基づいて更新する工程を含んでいてもよい。
上記方法は、上記第1の領域に対する上記予想値から導き出される第1の調整、および上記第2の領域に対する上記予想値から導き出される第2の調整を効果的に適用することによって上記検査値を更新する工程を含んでいてもよく、上記第1の調整は、上記第2の調整に対して用いられる演算子に対して反比例関係(inverse relationship)にある演算子を用いる。
上記方法は、上記第1の領域に対する上記予想値および上記第2の領域に対する上記予想値から導き出される中間値を演算することによって、上記第1の調整および第2の調整を共に適用する工程と、演算された上記中間値から導き出される上記検査値に対して、単一の調整を適用する工程とを含んでいてもよい。
上記中間値は、コンパイル中に事前に演算されてもよい。
上記方法は、上記第1の調整および第2の調整を、上記検査値に別々に適用する工程を含んでいてもよい。
上記第1の調整のための上記演算子は減算演算であってもよく、上記第2の調整のための上記演算子は加算演算であってよい。
上記第1の調整のための上記演算子は排他的論理和演算であってよく、上記第2の調整のための上記演算子は排他的論理和演算であってもよい。
少なくとも一部の領域あるいは機能ユニットに対する上記各予想値は、上記プログラムコードから直接取り出すことができる。
上記方法は、少なくとも一部の領域あるいは機能ユニットに対する上記各予想値を、異なるメモリ領域に記憶する工程と、領域あるいは機能ユニットに対する上記予想値を、適切な上記メモリ領域から必要時に取り出す工程とを含んでいてもよい。
少なくとも一部の予想値は、乱数または擬似乱数であってもよい。
少なくとも一部の予想値は、その対応する各領域または機能ユニットのメモリ領域の入力点から導き出すことができる。
上記方法は、上記少なくとも一部の予想値をハッシュ技術を用いて導き出す工程を含んでいてもよい。
上記方法は、ランダムにアクセス可能なメモリ領域に第3の検査値を提供する工程と、領域が、コール領域からコールされるコードの機能ユニットを有している場合は、上記コール領域に実行を戻す工程と、実行が上記機能ユニットに入る前に、上記第3の検査値を、上記コールに関連する値を有するように更新する工程と、少なくとも1つの上記のような機能ユニットから実行が戻った後に、上記第3の検査値が上記コールに関連する上記値を有しているか否かを判別する工程とを含んでいてもよい。
上記方法は、上記第3の検査値判別工程を、実行が上記コール領域に戻る前に行う工程を含んでいてもよい。
上記方法は、上記コールに関連する量の調整を与えることによって、上記第3の検査値を更新する工程と、上記調整を上記と同量だけ逆にすることによって上記第3の検査値が上記コール前調整が行われる前の値に戻るか否かを判別することによって、上記第3の検査値が上記コールに関連する上記値を保持しているかを、実行が戻った後に判別する工程とを含んでいてもよい。
上記方法は、上記第3の検査値を、上記コール前調整が行われる前の値に戻すために更新する工程を含んでいてもよい。
上記工程は、実行前に上記プログラム内に含まれていた命令によって行うことができる。
プログラム実行は、プログラムカウンタによって制御することができる。
上記デバイスは、セキュリティデバイスを含んでいてもよい。
上記デバイスは、スマートカードを含んでいてもよい。
本発明の第2の形態によると、複数の領域を介して進む実行パスに従ってデバイス上において実行されるプログラムを、予期せぬメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクなどの物理的妨害によって生じる実行フローエラーから、少なくともある程度は保護する方法であって、ランダムにアクセス可能なメモリ領域に第1の検査値を提供する工程と、少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否かを判別する工程と、第1の領域から、上記のような判別が成される第2の領域へと実行が通過するときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する工程と、上記のような判別が否定的であった場合にエラー処理手順を行う工程とを含むように、上記プログラムを変換する工程を含んでいる方法が提供される。
上記プログラムは、Cプログラミング言語などの高級プログラミング言語において特定することができる。
上記方法は、上記プログラムをコンパイルして、実行のための機械コードを上記デバイスによって直接生成する工程を含んでいてもよい。
本発明の第3の形態によると、予期せぬメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクなどの物理的妨害によって生じる実行フローエラーから少なくともある程度は保護されるプログラムであって、複数の領域を介した実行パスに従って実行されるプログラムがロードされたデバイスであって、ランダムにアクセス可能なメモリ領域に第1の検査値を提供する手段と、少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否か否かを判別する手段と、第1の領域から、上記判別が成される第2の領域へと実行が通過するときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する手段と、上記判別が否定的であった場合にエラー処理手順を行う手段とを含んでいるデバイスが提供される。
本発明の第4の形態によると、デバイス上において実行されるときに、当該デバイスに、本発明の上記第1の形態または上記第2の形態に係る方法を実施させるプログラムが提供される。
本発明の第5の形態によると、デバイスにロードされるときに、上記デバイスを、本発明の上記第3の形態に係るデバイスにするプログラムが提供される。
上記プログラムは、キャリア媒体上において実行することができる。当該キャリア媒体は、伝送媒体であってよい。当該キャリア媒体は、記憶媒体であってよい。
〔図面の簡単な説明〕
例として、添付図面を参照されたい。添付図面は、以下の通りである。
図1は、本発明の第1の実施形態の動作を示す図である。
図2は、本発明の第2の実施形態の動作を示す図である。
図3は、本発明の一実施形態を用いて実施可能な一スキーム(scheme)における様々な段階を示すブロック図である。
図4は、本発明の一実施形態に係る保護されたプログラムを実行するようにプログラムされたデバイスと、そのようなデバイスにおける様々な攻撃ポイントを示すブロック図である。
〔発明の最良の実施形態〕
本発明の一実施形態は、上述した従来の方法を考慮に入れながら、プログラムカウンタがプログラマーの予期せぬルートでコード内の特定のポイントに達した場合、CPUがこれを検出して保護処置(例えば、デバイスの終了または他のタイプのエラー処理ルーチンの実行)を講じることができるようにするための補助をする、ソフトウェアフロー制御検査を提案する。
以下では、本発明の実施形態について、C言語で書かれたソースコード、あるいはその簡略されたサブセットを参照しながら説明する。
具体的には、通常のC言語構文によると、“=”は代入を示し、“+=”はインクリメント代入(incrementing assignment)を示し、そして“==”は等価試験を示すために用いられている。
「関数」という用語は、単位として存在する1つのコードを示すために用いられている。関数は、通常のソフトウェア工学の実施においては、名前および明確な動作を有している。これは、C言語では実際に関数と称される。しかし、一部のコンピュータ言語では、同一の概念に対して、「サブルーチン」、「手順」、あるいは「方法」という用語が用いられている。
「故障」および「誤り」という用語は、一般的には置き換え可能に用いられており、意図的および偶発的に引き起こされたシステムの誤動作を示している。
構文“[]”は、例えばr[c]、s[c]、e[c]などの添字を示すために用いられている。
本発明の一形態を実施する方法は、プログラムカウンタを変更する攻撃に対して安全性を高めるために、ソースコードを変換する工程を含んでいる。
このような方法では、プログラムコードを複数の領域に分割して、ランダムだが固定した値r[c]を各領域cに与えると考えることができる。グローバル変数wisbは、プログラムカウンタが領域c内のコードを示すときは常に、wisb==r[c]であることを意図して定義されている。プログラムカウンタが領域cから新しい領域c’へと正確に移動できるときは常に、この変換によって、wisbの以前の値を新しい値r[c’]に変換するためのステートメントが挿入される。領域内のコードは、wisbの値が正しいかを確認するために(および、正しくない場合は適切な処置を講じるために)、必要に応じて変換させることができる。これによって、wisbへの代入によって合致しない、領域間におけるあらゆる制御フローが潜在的に検出される。
wisbを、wisb=r[c’]と単純代入するのではなく、以前の値およびr[c’]-r[c]の値に設定することが好ましい。これによって、また古い値がr[c]であったと仮定することによって、新しい値はr[c]+(r[c’]-r[c])となる。この値は、r[c’]と等しい。しかし、何らかの故障によって古い値が不正確であった場合(すなわちr[c]と等しくなかった場合)、新しい値もまた同量分、不正確となり、実行の残りの部分においても不正確のままとなる(偶然を除く)。従って上記値は、早急に検査されない場合であっても、後に検査されることになる。
このようにwisbは、一旦不正確となると、(高い確率で)不正確であり続けるという、「エラー伝搬」特性を有していると考えられる。これは、セキュリティおよびエラー検出において通常の特性である。
〔第1の実施形態〕
本発明の第1の実施形態について、図1を参照しながら説明する。図1は、保護される関数fを呼び出す、保護される関数mを示している。
保護されるべきプログラム(あるいはサブプログラム)Pがあると仮定する。
Pのいずれの部分が保護されるべきなのかが決定される。本実施形態では、全関数のみを保護するものと決定する。これによって、C={c1, c2, ...cn}が、保護されるPにおいて決定される全ての関数名をとるのに好都合となる。変換ユーティリティは、保護プロトコルに適切に従うために、コールする側とコールされる側との両方の保護状態を知っていなければならない。少なくとも1つの関数が保護され、保護されない関数は、保護される関数を呼び出さないものと仮定する。
入力xを受け付けるfunction_assert(x)が与えられ、xが真である場合、単純に、呼び出す側に戻るものと仮定する。xが偽である場合、何らかの故障警告が機能するか、あるいはエラー処理ルーチン(例えばデバイスのリセット)が動作する。上記function_assert()は、一般的に、本発明の一実施形態において保護される関数のうちの1つではなく、多くの場合、プラットフォームによって提供される低レベルコールである。
Cにおける各cに対して、2つの値s[c]およびe[c]が定義される。“s”および“e”は、それぞれ“開始(start)”および“終了(end)”を示している。s[c]およびe[c]は、セキュリティのために、その(整数)データ型に対して可能な全集合に及ぶ範囲の中から無作為に選択されることが望ましい。s[c]およびe[c]は、攻撃の複製を防止するために、デバイスが起動される度に無作為に生成されることが好ましい。しかし、本実施形態では、これらの値は定数であるものと仮定する。
グローバル変数wisbは、s[c]およびe[c]の値と同一のデータ型によって宣言され、また初期値s[main]を与える。「main」は、Pにおいて定義される最も外側の関数(Pに対して意図される唯一の開始点)である。この関数は、Cプログラミング言語では実際に「main」と称される。既述した条件により、本実施形態では、mainは、保護される関数であると保証される。
Cにおける各cに対して、関数cは、そのボディーコードB[c]を、変更されたコードB’[c]と置換することによって変更される。B’[c]は、以下の様に定義される。
B’[c]の実行前に、当該構造は、何らの故障も引き起こされていない場合は、wisb==s[c]が真であることを保証する。B’[c]は、終了すると、故障がない場合はwisb==e[c]が真であることを保証する。
INIT[c]を、ステートメント“_assert(wisb==s[c]);”となる様に定義する。
TERM[c]を、ステートメント“wisb += e[c] - s[c];”となる様に定義する。
まずB[c]を書き換えて、各内部コールを、保護される関数に変更する。可能な限りこれを分かり易くするために、まず、保護される各関数コールが、“X = F(Y);”というステートメントとして独自に書き込まれるものとする。上記Xは、(任意の)仮引数Yを有する関数Fの(任意の)結果を記憶するために用いられる(任意の)変数である。既にこのような状態になっていない場合でも、このような状態にするのは簡単である。
各“X = F(Y)”を以下のステートメントによって置換する。
{wisb += s[F] - s[c];
X = F(Y);
_assert(wisb == e[F]);
wisb += s[c] - e[F];}
あらゆる“return X;"ステートメント(Xは任意の戻り値)もまた、“{TERM[c]; return X;}”によって置換される。これは、B[c]が意図的に早く終了した場合を対処する。別の方法としては、“return”ステートメントを用いずにB[c]を書き換えるという方法もあるが、これはより複雑である。
変更された部分(すなわち、全ての関数コール、および上述したように置換された戻りステートメントを有するB[c])は、BB[c]と称される。
次に、B’[c]を、“INIT[c]; BB[c]; TERM[c];”となる様に定義する。
(BB[c]を通過する全ての可能な実行パスが戻りステートメントを終了した場合、最終的なTERM[c]は省略可能である。)。
故障がない状態において、wisbは、B’[c]が実行を開始したときにs[c]と等しい場合、終了時(および、もし終了する場合)には、e[c]と等しくなる。さらに、B’[c]が(保護される)関数fを呼び出す場合は常に、wisbの値は、fの開始時にはs[f]となり、fの戻り時にはe[f]となる。図1では、二重括弧{{}}内の式は、故障がない状態において真であるように意図された値を示している。これらの式は、図1の理解を補助するために挿入されたものであり、コードの一部としては考えられない。
エラー伝搬特性に鑑みて、(故障のため)一旦wisbが不正確となると、如何なるコマンドによってもこれが自動的に訂正されることはないため、不正確のままである可能性が高い限りは、アサーションの検査は任意であってよいことに留意されたい。従って、エラーの検査は時折行えばよい。例えば、セキュリティ中心のアプリケーション(security-centred application)に対しては、セキュリティクリティカルな各動作の直前、永続ストレージを更新する各動作の直前、および外部へデータを送信する各I/O動作の直前に、最少集合の検査を行う。挿入するアサーションは、特定のアプリケーションによる必要性に応じて増減することができる。
次に、単純なプログラムに適用される変換の実施例を挙げる。
本実施例では、関数“main”が関数“docredit”を呼び出すものとする。関数“print”は、汎用関数であり、システムによって定義される。従ってここでは、関数“print”は、保護されるべきものとは考えられない。
保護されないコードは:
main(pin、amount){
if(pin != test)return;
print(docredit(x));
}

int docredit(int x){
balance = balance + x;
return balance;
}
となる。
上記コードはまず、“docredit()”のコールが“print()”のコール内部から出るように、以下に変換することができる。
main(pin、amount){
int y;
if(pin != test)return;
y = docredit(x);
print(y);
}
int docredit(int x){
balance = balance + x;
return balance;
}
次に、残りの変換が適用される。説明する目的のために、プリプロセッサ定数は、sMAINを読み出してs[main]を実施し、eMAINを読み出してe[main]を実施する等として定義される。なお、使用時には、代わりに乱数を補間することも可能であるが、これはリーダにとっては従うのがより困難である。

// constants for each function
// name(randomly generated)
#define sMAIN 56769
#define eMAIN 15637
#define sDOCREDIT 9493
#define eDOCREDIT 41322

int wisb = sMAIN;

main(pin、amount){
int y;
_assert(wisb==sMAIN); // INIT[MAIN]

if(pin != test)
{wisb += eMAIN - sMAIN; return;} // handling
// return

// handling function call:
{wisb += sDOCREDIT - sMAIN;
y = docredit(amount);
_assert(wisb == eDOCREDIT);
wisb += sMAIN - eDOCREDIT;}

_assert(wisb==sMAIN); // added check
print(y);

wisb += eMAIN - sMAIN; // TERM[MAIN]
}

docredit(int amount){
_assert(wisb==sDOCREDIT]); // INIT[DOCREDIT]

balance = balance + amount;

{wisb += eDOCREDIT - sDOCREDIT; return;}

// no TERM required(return is always used)
}
多くのコンパイラは、実行をより効率的にするために、定数式(「定数畳み込み」)を単純化する点について留意されたい。例えば、“wisb += eMAIN - sMAIN;”を“wisb += -41132;”に低減することができる。これによってセキュリティに影響が及ぼされることはない。
また、機密データを偶発的に印刷しようという試みを捕捉するために、印刷直前にさらなるアサーションが追加された点についても留意されたい。
〔第2の実施形態〕
次に、本発明の第2の実施形態について、図2を参照しながら説明する。
第1の実施形態では、関数fが戻るときは常に、wisbの値はe[f]でなければならないという制限がある可能性がある。しかしfは、ソースコード内の2つ以上のポイントからコールされる場合もある(fは「多重コール側(multi-caller)」関数と言われる)ため、上記スキームは、fを誤ったコール側に戻すグリッチに対して保護を行わない。例えば、m1およびm2が双方ともfを呼び出すように設計されている場合、グリッチによって、fが、例えm1から呼び出された場合であってもm2に戻される可能性がある。wisbの値は、いずれの場合にも同じe[f]であるため、第1の実施形態のプロトコルでは故障を検出することができない。
第2の実施形態では、第2の保護層を追加するために、グローバル状態に余剰変数パス(extra variable path)が導入および初期化される。これは、第2の実施形態では、無作為な値に導入されることが好ましい。
前述同様、cがコールされると、{{wisb == s[c]}}であることが保証され、cが終了すると、{{wisb == e[c]}}であることが保証される(図1と同様、図2では、二重括弧{{}}内の式は、故障がない状態において真であるように意図された値を示している。これらの式は、図2の理解を補助するために挿入されたものであり、コードの一部としては考えられない)。さらに、関数fがコールされる前(および、wisbが更新される前)に、ローカルコピー(local copy)pにパスの値が記憶される。次に、公知の方法を用いて、(一定の)無作為な値Rを加算することによってパスが変更される。当該Rは、特定の関数コールに固有の値である。上記関数が戻り、wisbが更新された後、パスpの値がRと等しいかどうかが決定される。そして、Rを再び減算することによって、パスがリストアされる。
この方法の保護領域は、wisbがs[f]と等しい領域の上位集合である。なお、fが多重コール側関数である場合、wisbの構造では、そのような領域を区別することができない点について思い出されたい。従って、コードにおける上記のような各領域には、異なる値(R)のパスpが与えられる。関数が何らかの理由で不正確な領域に戻った場合、wisbが不正確となるか、あるいはパスpが不正確となるかのいずれかとなる。パスの調整前に_assert(path - p == R)を得る代わりとして、_assert(path == p)ステートメント前に-= Rであるパスを調整することができる。
INIT[c]およびTERM[c]を前述同様に定義する。ここでもまた、前述同様に、関数コールを正準形Y = F(X)に変換する。このような各関数コールに対して、一定の乱数Rを生成し、そして関数コールを以下の様に置換する。
{int p = path; path += R;
wisb += s[F] - s[c];
Y = F(X);
_assert(wisb == e[F]);
wisb += s[c] - e[F];
_assert(path - p == R);
path -= R;}
なお、全ての関数コールに対して上記方法を用いる必要はないことに留意されたい。変更される必要がある関数は、(例えば多重コール側関数を呼び出すため)「危険がある」と考えられるもののみである。他の関数は、第1の実施形態による上記方法を用いることができる(あるいは、完全に保護されていない状態としておくことができる)。
上記方法に必要なのは、第1に、上記方法を用いる各関数に対する1つの余剰グローバル変数、パス、および多くとも1つのローカルストレージ場所pである。ローカルストレージpは、スタック上に保持することができる。これによって、それが保護する関数がアクティブである(あるいは、それに戻るためのコールを待っている)ときのみにストレージを使用するという利点がある。保護される各pは、p[c]としてグローバルストレージに保持することができる。
上記方法の代わりとしては、多重コール側関数fへの各コールポイント1, 2... kは、(必要に応じて、)s[f]およびe[f]、例えばs[f][1]、s[f][2]、...s[f][k]およびe[f][1]、e[f][2]、...e[f][k]に対して異なる値を用いることができる点を除いては、第1の実施形態による方法が用いられる。関数fは、wisbがs[f][i]のいずれか1つと等しいことを検査し、最終的には適合しているe[f][i]に戻る。Fによって読み出される、保護されるあらゆる関数はまた、複数の関連付けを有している可能性がある。このため上記のような方法は、管理不可かつ非効率となる場合がある。
〔第3の実施形態〕
本発明の第3の実施形態について説明する。
2つの第1の実施形態は、関数ユニット全体のみを保護する。これらの実施形態では、関数m内におけるwisbの値は、INIT[m]の後かつTERM[m]の前における任意のソース位置s[m]であるが、関数コール付近のセットアップまたはクリア中は、そうではない。(この領域は、図1において点描で示されている)。第2の実施形態では、m本体の内部において関数fが複数回コールされる場合、保護は行われなかった。従って、fの一方のコールからfの異なるコールへの誤った戻りは検出されない。
第3の実施形態では、関数本体は、複数の小さい領域へとセグメント化されると考えられる。各領域は、関数全体を保護する方法と同様の方法によって保護される。
本実施形態を、関数に分割されない「モノリシック」コードに適用することができる。この場合、関数は1つのみであり、当該関数はコード全体を含んでいるものと考えられる。(プログラムが開始する)開始点は1つのみであり、終了点はない可能性がある(プログラムが非終端である場合)。
説明のため、および、一般的にあらゆる状況において適用可能な方法を提供するために、以下の要素から成る、再帰的に定義された簡易言語を用いて考察する:
「コードセグメント」Sは、以下のいずれかである。
A
(保護されない)関数の代入あるいはコールなどのアトミックステートメント、あるいは空のステートメント(“{}”で示される)。
F
アトミックステートメントのようなステートメント。しかし、保護される関数のコールは厳密に1つであり、また関数名はFUNC(F)という標記を用いて検索される。例えば、FUNC(“a = 3 + f(x*g(y))”)は、“f”(fは保護され、gは保護されないものと仮定する)と等しい。
D: S
一部のローカル変数Dが宣言されるセグメントS。範囲はS。
S1; S2
順次実行される2つのセグメント、S1とS2との複合。最初に実行されるのはS1。
while(E)S1
式Eが真である場合にセグメントS1が置換されるループ構造。Eは、保護される関数のコールを含んでいてはならない。
if E S1 S2
Eを評価し、Eが真である場合にS1を行い、Eが偽である場合にS2を行う条件付き構造。Eは、保護される関数のコールを含んでいてはならない。
return E
現在の関数から出てコール側に戻る、戻りステートメント。戻り値Eは任意。Eは、保護される関数のコールを含んでいてはならない。
括弧{...}は、曖昧にならないように項をグループ分けするために用いられている。
「プログラム」であるPは、グローバル変数および関数の定義の集合である。各関数fは、コードセグメントである本体、B(f)を有している。「メイン」関数であるMAIN(P)があり、これはPの開始点である。
また、単純な理由により、Pは変数名「wisb」は述べないものとする。Pが変数名「wisb」を述べると、その名前は新しい名前によって完全に置換されることになる。当業者であれば、現実世界のプログラムは、この形式で機械的に1つに簡略化できることを容易に理解できるであろう。この簡略形式(reduced from)によって得られる簡素化は必須ではないが、変換の既述をより簡素にすることができる。
さらに重要な点としては、本願に記載の教示内容を用いることによって、中間物(intermediate)として簡略形式を明示的に用いることなく、元のプログラムに変換をいかに適用するかが当業者には明らかとなるであろう。
a,b,c,dを、整数定数を表すメタ変数とする。
#aを、任意のステートメント“_assert(wisb == a)”であると定義する。当該ステートメントは、変換によって与えられた通りに挿入することができ、あるいは挿入しなくてもよいという意味で任意である。いずれの場合も、全てのアサーションが除外された場合は保護が行われないという前述の条件において、許容可能な変換のインスタンス化であると考えられる。
T(a,b)を、aがbと等しくない場合はセグメント“#a; wisb += b - a; #b;”であると定義し、aがbと等しい場合は“#a”であると定義する。
aおよびbを定数であると仮定すると、変換a<<S>>bは、Sの構造における再帰によって、セグメントSにおいて以下の様に定義される。
一部の新しい無作為な値cに対して、
a<<A>>b = #a; A; T(a,b);
a<<F>>b = #a; T(a,s[FUNC(F)]); F; T(e[FUNC(F)]、b)
a<<D: S>>b = D: {#a; a<<S2>>b}
a<<S1;S2>>b = #a; a<<S1>>c; c<<S2>>b
一部の新しい無作為な値cに対して、
a<<while(E)S>>b = #a; while(E){T(a,c); c<<S>>a}; T(a,b)
一部の新しい一対の無作為な値c、dに対して、
a<<if(E)S1 S2>>b
= #a; if(E){T(a,c); c<<S1>>b} {T(a,d); d<<S2>>b}
a<<return E>>b = T(a、e[f]); return E
ここでfは、囲んでいる関数である。
B(f、S)を定義する、すなわち関数fの本体Sの変換は、
一部の新しい一対の無作為な値s[f]、e[f]に対して、
B(f,S)= s[f]<<S>>e[f]
となる。
プログラムPの変換P’は、次の様に定義される。まずPから開始し、Pにおいて定義される保護される各関数fに対して、ランダム定数(random constant)s[f]およびe[f]の定義を加える。値s[MAIN(P)]に初期化された、wisbのグローバル定義(global definition)を加える。Pにおいて保護される各関数fに対して、fの本体SをB(S)によって置換する。Pにおいて保護されない各関数gに対して、gが保護される関数fを呼び出すときは常に、fのコール直前にステートメントwisb=s[f]を挿入する。結果P’を呼び出す。
上記定義には、テスト#aの挿入決定、および定数の選択において、大幅な選択の自由が含まれている。もし#aが強制的なアサーションとして扱われ、全ての定数が新しものとなるように選択された場合、変換されるプログラムはやや大きくなるが、非常によく保護されたプログラムとなる。
連続ステートメント“T(a,b); T(b,c)”を単一のT(a,c)によって変換して、プログラムサイズを縮小することができる(また、セキュリティを強化できる場合もある)。
必要に応じて、(aがbと等しいときのTの定義に従って)ランダム定数cおよびdを他のランダム定数と同じになるように選択して、多くのT(a,b)ステートメントがゼロになるようにすることができる。
以下に一例を示す。この例は、保護されないコードであるものとする:
main(){
x = 1;
y = 2;
return;
}
これは、まず以下の様に変換される。
int wisb = s[main]; // global
const A=84756387、B=48976230; // random constants
const sMain=45732576、eMain=2098573;
main(){
_assert(wisb == sMain); //optional
x = 1;
_assert(wisb == sMain); //optional
wisb += A - sMain;
_assert(wisb == A); //optional
y = 2;
_assert(wisb == A); //optional
wisb += B - A;
_assert(wisb == B); //optional
wisb += eMain - B;
_assert(wisb == eMain); //optional
return;
_assert(wisb == B); // optional:
// note: cannot reach here
}
一部の任意の_assertsが削除されると、以下のようになる。
int wisb = s[main]; // global
const A=84756387, B=48976230; // random constants
const sMain=45732576, eMain=2098573;
main(){
_assert(wisb == sMain); //optional
x = 1;
wisb += A - sMain;
_assert(wisb == A); //optional
y = 2;
wisb += B - A;
wisb += eMain - B;
_assert(wisb == eMain); //optional
return;
}
wisbインクリメントを組み合わせることによって、以下の様になる。
int wisb = s[main]; // global
const A=84756387; // random constants
const sMain=45732576、eMain=2098573;
main(){
_assert(wisb == sMain); //optional
x = 1;
wisb += A - sMain;
_assert(wisb == A); //optional
y = 2;
wisb += eMain - A;
_assert(wisb == eMain); //optional
return;
}
Aがs[main]と同じになるように選択されている場合は、以下の様になる。
int wisb = s[main]; // global
const sMain=45732576、eMain=2098573;
main(){
_assert(wisb == sMain); //optional
x = 1;
y = 2;
wisb += eMain - sMain;
_assert(wisb == eMain); //optional
return;
}
定数sMainおよびeMainは、メモリ内に記憶されて実行中に読み出されるのではなく、コンパイラによってコード内に構築されることが好ましい。
〔第4の実施形態〕
本発明の第4の実施形態では、多重コール側関数が故障によって不正確なコール側に戻らないように保護が行われる。第3の実施形態では、関数fの各コール側は、wisbが戻り時にe[f]に設定されて、wisb自体がこの種のエラーを検出できないようになることを期待している。
第3の実施形態の変換は、第2の実施形態が第1の実施形態から導かれた方法と同様の方法によって変更される。これは以下の通りである。
余剰グローバル変数パスを加算する。保護される関数コールの節を置換することによって、_<<_>>_の定義を変更する。
a<<F>>b =
#a;
declare p:
{
p = path; path+=R;
T(a,s[FUNC(F)]); F; T(e[FUNC(F)]、b);
_assert(path - p == R); path-=R;
}
ここでpは、Fでは用いられていない新しい変数名である。
パスが、wisbのようなエラー伝搬特性を有していることを考慮すると、上記_assertステートメントは、パスがその時点において正確な値を有していることを保証するために少なくともプログラム内のどこかに_assertステートメントが含まれているのであれば、任意として処置することができ、またこれと共にローカル変数pを使用することもできる。これによって、より効率的(用いるストレージを減らして、速く)実行を行うことできる。これらを任意として扱うことによって、以下の様になる:
a<<F>>b =
#a;
{
path+=R;
T(a,s[FUNC(F)]); F; T(e[FUNC(F)]、b);
path-=R;
}
〔第5の実施形態〕
あるいは、関数本体において保護される全ての関数コールは、1つのローカル変数pを共有することができる。これを、本発明の第5の実施形態として考えることができる。
a<<F>>b =
#a; path+=R;
T(a,s[FUNC(F)]); F; T(e[FUNC(F)]、b);
_assert(path - p == R); path-=R;
関数本体変換Bもまた、以下の様に変更される。
B(f、S)= declare p: {p=path; s[f]<<S>>e[f]}
ここでpは、Sにおいて表されない新しい変数名である。
〔第6の実施形態〕
MAINが保護される関数ではない場合であっても、本発明の一実施形態を用いることができる。この制限を緩和することによって、保護されない関数uが、保護される関数pを呼び出すことも可能となる。これを、本発明の第6の実施形態として考えることができる。
uの本体が、ステートメントx = p()を含んでいるものとする。これは、以下によって置換することができる。
declare tmp:
{tmp = wisb:
wisb = s[p];
x = p();
#(e[p]);
wisb = tmp;}
保護される関数が、(他のコールを介して直接的または間接的に)uを呼び出すことができない場合、wisbの古い値を記憶する必要はなく、あるいはこれを、pをコールた後にリストアする必要はない。
〔一般例〕
図3は、本発明の一実施形態を用いたスキームの一形態の様々な段階を示すブロック図である。第1の段階S1では、上述のセキュリティ変換手順を用いて、保護されないソースコード2が保護されるソースコード4に変換される。第2の段階S2では、保護される当該ソースコードがコンパイルされて、標的デバイス6内にロードされる。第3の段階S3では、コンパイルされた保護される上記コードが、標的デバイス6において実行される。第3の段階S3中において、一時的エラーまたはグリッチ攻撃が生じる。これは、上述のコンパイルされた保護されるコードに含まれている工程によって検出される。この結果、ハードウェアがリセットされるか、あるいはその他のエラー処理ルーチンS4が行われる。図4は、本発明の一実施形態に従って保護されるプログラムを実行するようにプログラムされたデバイス10のブロック図を示している。デバイス10は、記憶部12、中央演算処理装置(CPU)14、プログラムカウンタ(PC)16、入力/出力装置18、および電源装置20を備えている。図4は、このようなデバイスにおける様々な種類の攻撃ポイントの例を示している。
本発明の実施形態について、C(の簡略化された部分集合)で書かれたソースコードを参照しながら説明した。しかし本発明の一実施形態は、幅広い種類の任意の手続き型コンピュータ言語(例えば、C++、Java(登録商標)、Pascal、Fortran、Basic、C#、Perl等)を用いて実施できることについて理解されたい。通常の能力を有するソフトウェアエンジニアであれば、本願に記載されている教示内容を、他の言語に容易に適用することができるであろう。本発明の一実施形態はまた、アセンブリ言語または機械コードなど、コンパイラによって生成可能な低級言語を用いることができ、あるいはこのような言語に適用することができる。
元の(保護されていない)プログラムを系統的に変換することによって、ソフトウェア全体において検査を行うことができる。これによって、物理的なグリッチ型攻撃からの保護など、本願に記載の技術的利点を実現する、保護されたプログラムを得ることができる。この意味においては、ソフトウェア変換工程のみによって、実際的かつ重要な技術的利点がもたらされる。変換は、手入力、自動によって行うことができ、または、ある程度はこれら両極端の手段の中間を用いて行うことができる(例えば微調整時)。
検査自体はソフトウェア処理であるため、保護しているプログラムと同類の攻撃に対する抵抗を示すことが望ましい。
本発明の一実施形態を効果的に実施するために、Cコンパイラが上記スキームを過剰最適化してセキュリティが完全に消失しないようにする必要がある。wisbおよびパスを「揮発性の」変数として定義し、直接代入後であってもコンパイラがその値について何も仮定しないようにする必要がある場合がある。
定数s[]およびe[]は、インクリメント(例えばe[main] - e[f])の分布が適切に拡散されるように、無作為に選択されることが好ましい。しかし、s[f]およびe[f]を、例えばfのコード開始点のアドレスから、一種のハッシュ技術(SHA-1などの暗号学的ハッシュはここでは不要である)を用いて導き出すことができる。例えば、s[f] =(int)(f)/3; e[f]=(int)(f)。
個々の検査ステートメントは、任意ではあるが、上記技術を効果的にするためには少なくとも一部は必要であることを理解されたい。検査ステートメントが多いほど、より早く攻撃が検出される。クリティカルな演算(例えばフラッシュ更新またはI/O)の直前の検査を任意だとは考えないという方針にしてもよい。
なお、上記変換に対して、提供される保護の種類を変化させることのない変更を加えることができることについて理解されたい。また、これらの変更は、特許請求の範囲に明記されている本発明の範囲内であると考えられる。
例えば、必ずしも加算および減算を用いてwisbを更新する必要はなく、同様の性質を有する他の算術演算を代わりに用いることもできる。一形態としては、加算と減算との両方を排他的論理和演算と置き換えて、更新が“wisb ^= b ^ a”の形式になるようにすることができ、またこのようにして「パス」変数を操作することもできる。
この種の変数更新を機能させるために必要な代数的性質は、以下の通りである。
A +(B - A)== B
上記は、機能しているデータ型の値AおよびBのためのものである。これは、通常は整数の部分集合であるが、必ずしもそうでなくてもよい。このような更新は、まず中間値“B - A”を演算して、その中間値に基づいて検査値wisbを調整するか、あるいは、wisbを“+B”および“-A”とは別々に調整するかのいずれかによって行うことができる。後者の場合、まず“+B”の調整を先に行うことが好ましい。なぜなら、“-A”の調整を先に行うことによって、通常は、これら調整の対の間にwisbが一定値(ゼロ)を帯びるからである。これはつまり、このような調整の対の一方の間から、このような調整の対の他方の間への予期せぬジャンプは検出されない可能性があることを意味している。また、負の値の加算は、正の値の減算と同じであるため、加算演算と減算とは本質的に等化であることに留意されたい。
記号“+”および“-”は、この特性を有する任意の演算によって置換可能である。例えば、
A -(B $ A)== B
(“+”を“-”によって置換し、“-”を“$”によって置換し、B $ A == A - B(オペランドの順序をスワップ)と定義する)
となる。
あるいは、
A ^(B ^ A)== B
(“+”と“-”との両方を“^”によって置換(排他的論理和))
となる。
言い換えると、ある種の逆の関係において有効となるためには、これら2つの演算が必要とされる。なお、排他的論理和自身は、この意味において逆の関係(inverse)である。
前述したように、一実施形態では、制御フローが割り込みされていないRAM変数を検査として1つ用いる。これは、コード内の異なるポイントにおいて、様々な量でインクリメントされる。いずれかのインクリメントが行われなかった場合、その時点から値は不正確となる。RAM変数は、高速検出のために頻繁に検証することができ、あるいは必要に応じて、効率のためにより低い頻度で検証することができる。
本発明の一実施形態は、以下のいずれか1つまたは1つ以上の利点を有している。
・コンパクト:RAM要件が非常に小さい。これは、一実施形態では、ネスト化された各関数コールに対して例えばスタックの1ワード(one word of stack)を用いる代わりに、符号化を行うために1つの変数が用いられるためである。
・簡素:変換が簡素であるため、マクロあるいはその他の自動ツールによって支援可能であり、あるいは完全自動化することができる。
・利便性:上記方法は、何らの構造的変化を加えることなく既存のコードに加えることができる。当該スキームはまた、グローバルプログラムフロー状態機械を演算することなく、コードの小部分に適用可能である。
・柔軟性:カバレージ(coverage)の質は、リソースの許す範囲で低くすることができ、あるいは高くすることができる。
・効率性:挿入される行が短く、実行が早い。
・有効性: スキップされた区域を検出する。制御フローに対する全体的変化を検出する。一旦エラーがセットされると、後のあらゆる時点において検出可能である(複合故障によって1つ以上の検査ステートメントがスキップされた場合であっても)。(例えば、US5,274,817はエラー伝搬特性を有していない。)
本発明の一実施形態を適用できる例としては、パスポートのチップ、スマートカードデバイス、他のハードウェアセキュリティデバイス、および一般的にあらゆるセーフティクリティカルおよびミッションクリティカルなセキュリティデバイスが含まれる。
提示されている本方法は、プログラムカウンタへの全てのグリッチ攻撃を防止する訳ではない。本方法は、例えば、条件付き分岐命令を不正確に受けさせる(あるいは受けさせないようにする)攻撃の大部分を検出しないであろう。本方法は、わずか一部の命令をスキップさせる故障を検出しない可能性がある。従って、本発明を実施する者は、さらに(例えば)複数のPIN検査および冗長な計算を追加して、クリティカルな結果を検査しなければならない。
本発明を実施するプログラムは、コンピュータ可読媒体に記憶させることができ、あるいは、例えば、インターネットウェブページによって供給されるダウンロード可能なデータ信号などの信号に組み込むことができることを理解されたい。特許請求の範囲は、プログラムそのものを網羅するものとして、あるいは担体上の記録として、あるいは信号として、あるいは他の任意の形式にあるものとして解釈される。
本発明の第1の実施形態の動作を示す図である。 本発明の第2の実施形態の動作を示す図である。 本発明の一実施形態を用いて実施可能な一スキーム(scheme)における様々な段階を示すブロック図である。 本発明の一実施形態に係る保護されたプログラムを実行するようにプログラムされたデバイスと、そのようなデバイスにおける様々な攻撃ポイントを示すブロック図である。

Claims (39)

  1. 複数の領域を介して進む実行パスに従ってデバイス上において実行されるプログラムを、予期しないメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクのような物理的妨害によって生じる実行フローエラーから、少なくともある程度は保護する方法であって、
    ランダムにアクセス可能なメモリ領域に第1の検査値を設ける工程と、
    少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否かを判別する工程と、
    第1の領域から、上記のような判別が成される第2の領域へと実行が進むときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する工程と、
    上記のような判別が否定的であった場合にエラー処理手順を行う工程とを含んでいる方法。
  2. 上記の判別工程を、クリティカルな性質(critical nature)を有する上記プログラムの少なくとも一部の演算の前に行う工程を含んでいる請求項1に記載の方法。
  3. 上記の判別工程を、上記検査値更新工程の少なくとも一部の前に行う工程を含んでいる請求項1に記載の方法。
  4. 上記の判別工程を、上記デバイスの持続ストレージを更新する上記プログラムの少なくとも一部の演算の前に行う工程を含んでいる請求項1、2または請求項3に記載の方法。
  5. 上記の判別工程を、上記デバイスの外部または上記デバイスの保護領域の外部にデータを送信させる少なくとも一部の演算の前に行う工程を含んでいる請求項1、2または請求項3に記載の方法。
  6. ランダムにアクセス可能なメモリ領域に第2の検査値を設ける工程と、
    領域が、コール領域からコールされるコードの機能ユニットを有している場合は、リターン領域に実行を戻す工程と、
    実行が上記機能ユニット外に進む前に、上記機能ユニットに対して予想される最終値を有するように、第2の検査値を更新する工程と、
    実行が上記機能ユニット外に進んだ後および実行が上記リターン領域に戻る前に、上記第2の検査値が上記予想される最終値を有しているか否かを判別する工程とを含んでいる請求項1、2または3に記載の方法。
  7. 上記リターン領域は上記コール領域と同一である請求項6に記載の方法。
  8. 上記第2の検査値は、同一のランダムにアクセス可能なメモリ領域を用いて、上記第1の検査値と同一であり、
    上記第2の領域において予想される上記値を有するように上記第1の検査値が更新される前に、上記第2の検査値が、上記予想される最終値を有しているか否かを判別する工程を含んでいる請求項6に記載の方法。
  9. 上記第2の領域に実行が進む前に上記更新工程が行われる上記第1の領域に実行が進むときに、上記第1の領域において予想される値を有するように上記第1の検査値を更新する工程を含んでいる請求項1、2または3に記載の方法。
  10. 上記検査値が予想外の値を一旦推定すると、後の上記更新においても予想外の値を保持する可能性を有するように、上記検査値を更新する工程を含んでいる請求項1、2または3に記載の方法。
  11. 上記更新された検査値が上記更新前に上記第1の領域に対する上記予想値を有している場合に限り、上記更新された検査値が上記第2の領域に対する上記予想値を有するように、上記検査値を、上記第2の領域に対するその予想値および上記第1の領域に対するその予想値に基づいて更新する工程を含んでいる請求項1、2または3に記載の方法。
  12. 上記第1の領域に対する上記予想値から導き出される第1の調整、および上記第2の領域に対する上記予想値から導き出される第2の調整を効果的に適用することによって上記検査値を更新する工程を含んでおり、
    上記第1の調整は、上記第2の調整に対して用いられる演算子に対して反比例関係(inverse relationship)にある演算子を用いる請求項11に記載の方法。
  13. 上記第1の領域に対する上記予想値および上記第2の領域に対する上記予想値から導き出される中間値を演算することによって、上記第1の調整および第2の調整を共に適用する工程と、
    演算された上記中間値から導き出される上記検査値に対して、単一の調整を適用する工程とを含んでいる請求項12に記載の方法。
  14. 上記中間値は事前に演算される請求項13に記載の方法。
  15. 上記第1の調整および第2の調整を上記検査値に別々に適用する工程を含んでいる請求項12に記載の方法。
  16. 上記第2の調整は上記第1の調整の前に適用される請求項15に記載の方法。
  17. 上記第1の調整のための上記演算子は減算演算であり、上記第2の調整のための上記演算子は加算演算である請求項12に記載の方法。
  18. 上記第1の調整のための上記演算子は排他的論理和演算であり、上記第2の調整のための上記演算子は排他的論理和演算である請求項12に記載の方法。
  19. 少なくとも一部の領域あるいは機能ユニットに対する上記各予想値は、プログラムコードから直接取り出される請求項1、2または3に記載の方法。
  20. 少なくとも一部の領域あるいは機能ユニットに対する上記各予想値を、異なるメモリ領域に記憶する工程と、
    領域あるいは機能ユニットに対する上記予想値を、適切な上記メモリ領域から必要時に取り出す工程とを含んでいる請求項1、2または3に記載の方法。
  21. 少なくとも一部の予想値は乱数または擬似乱数である請求項1、2または3に記載の方法。
  22. 少なくとも一部の予想値は、各領域または機能ユニットのそれぞれに対応する上記メモリ領域の入力点から導き出される請求項1、2または3に記載の方法。
  23. 上記少なくとも一部の予想値をハッシュ技術を用いて導き出す工程を含んでいる請求項22に記載の方法。
  24. ランダムにアクセス可能なメモリ領域に第3の検査値を設ける工程と、
    領域が、コール領域からコールされるコードの機能ユニットを有している場合は、上記コール領域に実行を戻す工程と、
    実行が上記機能ユニットに進む前に、上記第3の検査値を、上記コールに関連する値を有するように更新する工程と、
    少なくとも1つの上記機能ユニットから実行が戻った後に、上記第3の検査値が上記コールに関連する上記値を有しているか否かを判別する工程とを含んでいる請求項1、2または3に記載の方法。
  25. 上記第3の検査値判別工程を、実行が上記コール領域に戻る前に行う工程を含んでいる請求項24に記載の方法。
  26. 上記コールに関連する量の調整を与えることによって、上記第3の検査値を更新する工程と、
    上記調整を上記と同量だけ逆にすることによって上記第3の検査値が上記コール前調整が行われる前の値に戻るか否かを判別することによって、上記第3の検査値が上記コールに関連する上記値を保持しているか否かを、実行が戻った後に判別する工程とを含んでいる請求項24に記載の方法。
  27. 上記第3の検査値を、上記コール前調整が行われる前の値に戻すために更新する工程を含んでいる請求項24に記載の方法。
  28. 上記工程は、実行前に上記プログラム内に含まれていた命令によって行われる請求項1、2または3に記載の方法。
  29. プログラム実行はプログラムカウンタによって制御される請求項1、2または3に記載の方法。
  30. 上記デバイスはセキュリティデバイスを含んでいる請求項1、2または3に記載の方法。
  31. 上記デバイスはスマートカードを含んでいる請求項1、2または3に記載の方法。
  32. 複数の領域を介して進む実行パスに従ってデバイス上において実行されるプログラムを、予期しないメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクのような物理的妨害によって生じる実行フローエラーから、少なくともある程度は保護するために
    ランダムにアクセス可能なメモリ領域に第1の検査値を提供する工程と、
    少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否かを判別する工程と、
    第1の領域から、上記の判別が成される第2の領域へと実行が進むときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する工程と、
    上記の判別が否定的であった場合にエラー処理手順を行う工程とを含むように、入力されたプログラムをコンピュータが変換する方であって、
    プログラムカウンタが上記第1の領域内のコードを示すときは常に上記第1の検査値が上記予想値を有することを意図して第1の検査値を定義するステートメントを上記第1の領域より前に挿入する工程と、
    上記第1の検査値が上記予想値を有しているか否か確認するために上記第1の領域内のコードを変換する工程と、
    上記第1の検査値が上記予想値を有しているとき、上記第1の検査値が有する上記予想値を上記第2の領域において予想される値に変換するためのステートメントを挿入する工程と、
    上記第1の検査値が上記予想値を有していないときに起動する上記エラー処理手順を定義するステートメントを挿入する工程とを含んでいることを特徴とする方法。
  33. 上記プログラムは、Cプログラミング言語のような高級プログラミング言語において特定される請求項32に記載の方法。
  34. 上記プログラムをコンパイルして、実行のための機械コードを上記デバイスによって直接生成する工程を含んでいる請求項32または33に記載の方法。
  35. 予期しないメモリ領域へプログラム実行をジャンプさせるデバイス不具合および電圧スパイクのような物理的妨害によって生じる実行フローエラーから少なくともある程度は保護されるプログラムであって、複数の領域を介して進む実行パスに従って実行されるプログラムがロードされたデバイスであって、
    ランダムにアクセス可能なメモリ領域に第1の検査値を提供する手段と、
    少なくとも1つの領域において少なくとも一回は、上記第1の検査値が当該領域に対する予想値を有しているか否かを判別する手段と、
    第1の領域から、上記のような判別が成される第2の領域へと実行が通過するときに、上記第1の検査値を、上記第2の領域において予想される値を有するように更新する手段と、
    上記のような判別が否定的であった場合にエラー処理手順を行う手段とを含んでいるデバイス。
  36. 請求項1に記載の方法を上記デバイスに実施させるために、上記デバイス上において実行されるプログラム。
  37. 請求項32に記載の方法を上記コンピュータに実施させるために、上記コンピュータ上において実行されるプログラム。
  38. 請求項35に記載の上記デバイスにおいて構成されるコンピュータを、上記デバイスにおける各手段として機能させるためのプログラム。
  39. 請求項36、37または38に記載の上記プログラムを記録したコンピュータ読み取り可能な記録媒体。
JP2008535832A 2006-02-27 2007-02-26 制御フロー保護機構 Expired - Fee Related JP4754635B2 (ja)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
GB0603861A GB2435531A (en) 2006-02-27 2006-02-27 Control Flow Protection Mechanism
GB0603861.6 2006-02-27
PCT/JP2007/054115 WO2007100116A1 (en) 2006-02-27 2007-02-26 Control flow protection mechanism

Publications (2)

Publication Number Publication Date
JP2009525509A JP2009525509A (ja) 2009-07-09
JP4754635B2 true JP4754635B2 (ja) 2011-08-24

Family

ID=36178816

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2008535832A Expired - Fee Related JP4754635B2 (ja) 2006-02-27 2007-02-26 制御フロー保護機構

Country Status (4)

Country Link
US (1) US20090077415A1 (ja)
JP (1) JP4754635B2 (ja)
GB (1) GB2435531A (ja)
WO (1) WO2007100116A1 (ja)

Families Citing this family (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
GB2457062A (en) * 2008-02-01 2009-08-05 Iti Scotland Ltd Tag reader / writer process partitioned for execution between secure and non-secure processing environments
JP4701260B2 (ja) * 2008-03-31 2011-06-15 株式会社エヌ・ティ・ティ・データ 情報処理装置、情報処理方法、および、情報処理プログラム
US8302210B2 (en) 2009-08-24 2012-10-30 Apple Inc. System and method for call path enforcement
JP5470305B2 (ja) * 2011-03-04 2014-04-16 株式会社エヌ・ティ・ティ・データ セキュリティ試験支援装置、セキュリティ試験支援方法およびセキュリティ試験支援プログラム
CN104981813B (zh) * 2012-03-30 2018-08-07 爱迪德技术有限公司 使用动态数据识别编码来保护可访问的***
US9721120B2 (en) 2013-05-14 2017-08-01 Apple Inc. Preventing unauthorized calls to a protected function

Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH04259036A (ja) * 1991-02-13 1992-09-14 Nec Corp プログラム変換方式及びプログラム不正動作検出機構
JP2002334317A (ja) * 2001-05-09 2002-11-22 Hitachi Ltd 情報処理装置
JP2005509936A (ja) * 2001-11-16 2005-04-14 ギーゼッケ ウント デフリエント ゲーエムベーハー 携帯型データ記憶媒体により制御されるプログラム実行
WO2005073859A2 (fr) * 2003-12-31 2005-08-11 Trusted Logic Procede de controle d'integrite d'execution de programmes par verification d'empreintes de traces d'execution
JP2006053787A (ja) * 2004-08-12 2006-02-23 Ntt Docomo Inc プログラム実行装置及びプログラム実行方法

Family Cites Families (16)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5274817A (en) * 1991-12-23 1993-12-28 Caterpillar Inc. Method for executing subroutine calls
JP2846837B2 (ja) * 1994-05-11 1999-01-13 インターナショナル・ビジネス・マシーンズ・コーポレイション 障害を早期検出するためのソフトウェア制御方式のデータ処理方法
US5758060A (en) * 1996-03-05 1998-05-26 Dallas Semiconductor Corp Hardware for verifying that software has not skipped a predetermined amount of code
US6044458A (en) * 1997-12-12 2000-03-28 Motorola, Inc. System for monitoring program flow utilizing fixwords stored sequentially to opcodes
DE69924857T2 (de) * 1998-10-10 2006-03-02 Transitive Ltd., Hanging Ditch Programm-kode-umwandlung
JP2001066989A (ja) * 1999-08-31 2001-03-16 Fuji Xerox Co Ltd 一方向性関数生成方法,一方向性関数値生成装置,証明装置,認証方法および認証装置
US7188258B1 (en) * 1999-09-17 2007-03-06 International Business Machines Corporation Method and apparatus for producing duplication- and imitation-resistant identifying marks on objects, and duplication- and duplication- and imitation-resistant objects
US6751698B1 (en) * 1999-09-29 2004-06-15 Silicon Graphics, Inc. Multiprocessor node controller circuit and method
CA2305078A1 (en) * 2000-04-12 2001-10-12 Cloakware Corporation Tamper resistant software - mass data encoding
FR2819672B1 (fr) * 2001-01-18 2003-04-04 Canon Kk Procede et dispositif d'emission et de reception d'images numeriques utilisant un marqueur d'image pour le decodage
US7594111B2 (en) * 2002-12-19 2009-09-22 Massachusetts Institute Of Technology Secure execution of a computer program
US7536682B2 (en) * 2003-04-22 2009-05-19 International Business Machines Corporation Method and apparatus for performing interpreter optimizations during program code conversion
US7200841B2 (en) * 2003-04-22 2007-04-03 Transitive Limited Method and apparatus for performing lazy byteswapping optimizations during program code conversion
US7644287B2 (en) * 2004-07-29 2010-01-05 Microsoft Corporation Portion-level in-memory module authentication
US20080201689A1 (en) * 2005-06-30 2008-08-21 Freescale Semiconductor, Inc. Vector Crc Computatuion on Dsp
JP2008293076A (ja) * 2007-05-22 2008-12-04 Seiko Epson Corp エラー判定プログラム、エラー判定方法、及び、電子機器

Patent Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH04259036A (ja) * 1991-02-13 1992-09-14 Nec Corp プログラム変換方式及びプログラム不正動作検出機構
JP2002334317A (ja) * 2001-05-09 2002-11-22 Hitachi Ltd 情報処理装置
JP2005509936A (ja) * 2001-11-16 2005-04-14 ギーゼッケ ウント デフリエント ゲーエムベーハー 携帯型データ記憶媒体により制御されるプログラム実行
WO2005073859A2 (fr) * 2003-12-31 2005-08-11 Trusted Logic Procede de controle d'integrite d'execution de programmes par verification d'empreintes de traces d'execution
JP2007517299A (ja) * 2003-12-31 2007-06-28 トラステッド ロジック ソシエテ アノニム 実行トレースプリントを検証することによるプログラム実行整合性の制御方法
JP2006053787A (ja) * 2004-08-12 2006-02-23 Ntt Docomo Inc プログラム実行装置及びプログラム実行方法

Also Published As

Publication number Publication date
GB0603861D0 (en) 2006-04-05
GB2435531A (en) 2007-08-29
WO2007100116A1 (en) 2007-09-07
US20090077415A1 (en) 2009-03-19
JP2009525509A (ja) 2009-07-09

Similar Documents

Publication Publication Date Title
D'Silva et al. The correctness-security gap in compiler optimization
Alkhalifa et al. Design and evaluation of system-level checks for on-line control flow error detection
Moss et al. Compiler assisted masking
Cadar et al. Data randomization
US7779270B2 (en) Software self-defense systems and methods
JP4777903B2 (ja) 実行トレースプリントを検証することによるプログラム実行整合性の制御方法
US20080271001A1 (en) Method of generating program, information processing device and microcomputer
JP7154365B2 (ja) ソフトウェアコードをセキュアにするための方法
Proy et al. Compiler-assisted loop hardening against fault attacks
JP5467271B2 (ja) 情報処理装置及びプログラム、情報処理方法、記録媒体
JP4754635B2 (ja) 制御フロー保護機構
De Keulenaer et al. Link-time smart card code hardening
Goubet et al. Efficient design and evaluation of countermeasures against fault attacks using formal verification
CN101366035A (zh) 保护便携装置中的中间语言软件代码执行的安全的方法
Vankeirsbilck et al. Automatic implementation of control flow error detection techniques
US8423974B2 (en) System and method for call replacement
US11704128B2 (en) Method for executing a machine code formed from blocks having instructions to be protected, each instruction associated with a construction instruction to modify a signature of the block
Péneau et al. NOP-Oriented Programming: Should we Care?
Geier et al. Compasec: a compiler-assisted security countermeasure to address instruction skip fault attacks on risc-v
Vu et al. Reconciling optimization with secure compilation
US8458790B2 (en) Defending smart cards against attacks by redundant processing
Pescosta et al. Bounded model checking of speculative non-interference
JP2009009537A (ja) プログラム作成方法及び情報処理装置ならびにマイコン
Yao et al. A low-cost function call protection mechanism against instruction skip fault attacks
Verbeek et al. Highly Automated Formal Proofs over Memory Usage of Assembly Code

Legal Events

Date Code Title Description
A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20110222

A521 Request for written amendment filed

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20110422

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20110524

A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20110525

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20140603

Year of fee payment: 3

R150 Certificate of patent or registration of utility model

Free format text: JAPANESE INTERMEDIATE CODE: R150

LAPS Cancellation because of no payment of annual fees