図1は、本発明のためのありふれた用途、すなわちビデオゲームを表している。開示内容を読めば明白になるように、本発明はビデオゲームあるいはカートリッジ上に格納されるプログラムに限定されるものではない。
図1において、ゲーム機10にゲームカートリッジ12がバス14を介し今まさに接続されようとしている状態が示されている。ここでは、模倣者はゲームプログラム及びゲームデータをゲームカートリッジ12に格納される時に読み取ることができ、または模倣者はゲーム機10内で起こることを全て知っていると仮定する。また、セキュリティデバイスの好ましい設計プラクティスに従い、模倣者はキー又はパスワード以外は、どんなセキュリティ回路及びアルゴリズムも全て詳しく知っていると仮定する。システムの基本的な目的は正規ユーザがプログラムを走らせることができるようにすることであるので、模倣者が所与の入力データ・セットでプログラムを走らせてプログラムの結果と流れを観測することを妨げることは不可能である。したがって、このシステムの目標は、プログラムを通常速度で走らせること、そして、一つの入力データ・セットによりプログラムを1回実行することによって推測できるプログラムの情報量を制限することを要求することである。実際のプログラムコード及びデータを確認することが事実上不可能であるのは、システムに対して走らせなければならない入力データセットの数があまりに多いために、かかる解析を実施するのに必要な時間が、プログラムの適法な販売の大半が終わるまでの期間より長いか同等であるからである。
ゲーム機10は図示のように、プロセッサ20、ローカルメモリ22、ビデオディスプレイ16への出力インターフェイス、入力装置18からの入力インターフェイス及び回路クロック24を有する。ゲーム機10は図示されないが他のエレメントを持っているかもしれない。入力装置18は、本発明の主題ではないので包括的に示されているが、例えばキーボード、ジョイスティック、タッチパッド又はセンサーアレイである。ビデオディスプレイ16は通常、プロセッサ20又は中間ビデオメモリ(不図示)により指定された色の画素の2次元配列を表示する画素分割ディスプレイ(例えばラスターモニタ)である。ローカルメモリ22は、プログラムの実行に用いられる変数並びにプログラムのカレントページの命令を格納する。プログラムは必要になった時にローカルメモリ22にページングすることができるので、ローカルメモリ22はプログラム全体を同時に格納する必要はない。この説明から明らなように、セキュリティシステムをプロセッサ20すなわちゲームシステムのCPUに関連して説明するが、本発明はシステム内にあるビデオプロセッサ、画像プロセッサ、その他のプロセッサに関しても利用し得る。
図示されたゲームカートリッジ12は、セキュリティチップ30とROM(プログラムメモリ)32を有する。ROM32の代わりに別種の記憶手段、例えばCD−ROM(コンパクトディスクROM)、ディスケット、フラッシュメモリ、あるいはネットワーク経由でアクセスされるリモートプログラム等を用いてもよい。ROM32はゲームプログラムを暗号化された形で格納している。そのように格納されたプログラムは、プログラムの実行可能コード、データテーブル、グラフィック画像のほか、カートリッジにより実現されるゲームの動作に必要な又は関係した関連オブジェクトから構成される。好適な実施例では、セキュリティチップ30は単一の集積回路であって、外部アクセス可能なピンに保護データストリームは全く流れない。
本発明は、あらゆる攻撃に対し保護できるわけではない。例えば、模倣者がゲームメーカの不心得な従業員から暗号化前のゲームプログラムを手に入れたならば、模倣者がそのプログラムをそのままの形で頒布することを本発明は阻止できないであろう。ここでは、不正な模倣者はゲーム機といくつかのゲームカートリッジを入手できるだけであると仮定する。このように入手方法が限定された場合、模倣者は図1にツール40として示した様々な解析ツール及び制御ツールを利用し、ゲーム機及びカートリッジの動作解析を試みるであろう。解析ツールは信号を記録し、一方、制御ツールは信号を変化させるが、多くは同時に解析ツールで信号を記録する。このようなツールにはマイクロプロセッサ・トレースアナライザー、波形発生器、オシロスコープ等が含まれる。図1は、模倣者が信号の解析及び制御のためのタップを設ける可能性のあるゲーム機10及びゲームカートリッジ12内部のいくつかの箇所を表している。重要なことは、模倣者は、セキュリティチップ30の化学的隔離や顕微鏡レベルの作業を行わないと、セキュリティチップ30の内部信号線にタップを設けることができないことである。
回路クロック24に対するタップ41は、ゲーム機10の動作速度を下げてゲーム機10の動作解析を容易にするために、あるいは、回路クロック24の速度を上げて、より迅速に多くの命令を実行することによりプログラムの様々な変化をテストするために、利用されるかもしれない。このタップを利用できなくするため、セキュリティチップ30は内部的に速度が決定されるクロックも保有し、回路クロック24が正しい速度で動作しないとROM32からのプログラムデータの復号化を拒否してもよい。
ROM32に対するタップ42は模倣者にROM32の内容を提供するが、これらの内容はセキュリティチップ30によって提供される復号化がなければ役に立たない。バス14上を往来するデータに対するタップ44又はプロセッサ20とローカルメモリ22の間を往来するデータに対するタップ43は、復号化されたプログラム情報を提供するかもしれないが、しかし、ゲームの1実行に当てはまるプログラムシーケンスの例を提供するにすぎず、様々な入力セットに利用可能なシーケンスを提供するものではない。さらに、その情報は分岐命令を含まない。というのは、分岐命令はプロセッサへは送られず、セキュリティチップ30内で実行されるからである。
ビデオディスプレイ16に対するタップ45についても同じことが言える。タップ45は全てのビデオ信号を記録できるかもしれないが、ビデオ信号は単にゲームのある特定のプレイに対応するにすぎない。例えば、独特のグラフィックスを含むあるゲームレベルに決して到達しなければ、そのゲームレベルのグラフィックスはビデオディスプレイ16に決して送られないからタップ45により取得できない。
確信犯的な模倣者は、ゲームの様々な結果とイベントをシミュレートする信号を挿入するために入力装置18とプロセッサ20の間の信号に対するタップ46を利用するかもしれない。様々な十分なパスによって、模倣者はあらゆる可能性を確認してゲームプログラムを再現できるかもしれないが、プロセッサの速度を上げることができないため、また、極めて多くの可能性があるために、ゲームが市販されてから模倣者の潜在市場を拡散させるに十分な量が売れてしまうまでの間に、模倣者がゲームを再現できるとは思われない。
このように、これらのタップを全て用いたとしても、ゲーム機10とゲームカートリッジ12しか入手できない模倣者は、ゲームプログラムの完全な使用可能な複製を作ることができない。確信犯的な模倣者はセキュリティチップ30そのものに侵入するかもしれないが、それにはセキュリティチップ30のケースを注意深く取り除いてセキュリティチップ30を1層1層解析しなければならない。しかしながら、セキュリティチップ30の内部回路全体が分かったとしても、層を除去するとキーを保持しているメモリは電源を断たれるように設計されているため、模倣者はROM32の復号化に必要な揮発性のキー設定を得られないであろう。そのメモリが電源のために必要な層より何層も下にある場合、メモリはその層が解析に利用できるようになる前に消去されてしまうであろう。模倣者は、セキュリティチップ30を打破するには、ROM32の内容とセキュリティチップ30の出力を解析してキーを引き出すことができなければならない。キーはゲーム毎に異なることに加え(必ずしも各ゲームカートリッジはそのゲームを格納しているとは限らない)、セキュリティチップ30はその中身にアクセスせずに暗号を打破することをいっそう困難にする他の機構を含んでいる。
図2はセキュリティチップ30をさらに詳しく表す。セキュリティチップ30はバスユニット50を有し、これはセキュリティチップ30をバス14と結合し、プログラムデータを求める要求をトランスレータ52に渡す。トランスレータ52は、アクセス要求のアドレスをROM32のアドレスロケーション又はロケーション範囲へ変換する。このアドレスはアドレスバス54を介しROM32へ送られ、ROM32はデータをデータバス56で返す。あるいは、ROM32のいくつかのロケーションがキャッシュ60にキャッシュされてもよく、この場合にはトランスレータ52はアドレス情報をキャッシュ60へ送り、キャッシュ60はキャッシュデータを供給する。
両方のデータソースが復号化器62の入力に結合されるが、復号化器62はキーレジスタ64により与えられるキー値を使ってROM32からのデータを復号化する。後述のように、要求されるセキュリティの程度に応じて復号化器62は様々な構成をとり得る。復号化器62はほぼ、プログラムデータの暗号化に使用される暗号化器の逆装置でなければならないので、復号化器62の様々な構成を暗号化器と関連させて後述する。
復号化器62の出力はオプションの伸長器68の入力に与えられ、伸長器68はそのデータをルーター(router)70へ送る。ルーター70はクリア(clear)ROMデータ用出力と秘密データ用出力を持つ。クリアROMデータは暗号化されないプログラムコード及びデータオブジェクトであるが、分岐情報は持たない。秘密データは分岐情報並びに他の変数、例えばチェックサムと所期の実行時間を含む。
秘密データ出力は演算ユニット72に結合され、演算ユニット72はセキュリティチップ30の全体的制御を司る。演算ユニット72はプライベートテーブル74の読み書き用ポート、リアルタイムクロック76の読み込み用入力、バスユニット50から分岐要求を受け取るための入力、バスユニット50に結合される分岐応答用出力、プロセッサバスすなわちバス14上で発生するアクティビィティに関する情報を提供するバスタップのためのバスユニット50からの入力、プログラムデータの要求の妥当性に関するバスユニット50からの問い合わせを受け取って回答するためのポートも有する。セキュリティチップ30の詳細な動作については図4及び図5に関連して後述する。
図3は、ゲームカートリッジ12に使用されることになる暗号化ROM32にゲームプログラム112を暗号化するために利用されるシステム100のブロック図である。システム100は分岐セパレータ102に結合されるゲームプログラム112用記憶装置を有し、分岐セパレータ102は保護プログラム114、分岐テーブル116、チッェックサムデータのファイル118、タイミングデータのファイル120を出力する。これらデータセットのための記憶装置が用意されており、この記憶装置は圧縮器104に結合される。この圧縮器104はあってもなくてもよいが、ある方が望ましい。圧縮器104の出力は暗号化器108の入力に結合され、暗号化器108はキーレジスタ110からキー値を受け取るための入力も持っている。この暗号化器108の出力がROM32の内容を形成する。
前述のように、ゲームプログラム112はプログラムの実行可能コード、データテーブル、グラフィック画像、その他の関連オブジェクトからなる。説明用でしかないが、プログラムの実行可能コードの簡単な一例を表1に示す。表1に示すプログラムは、当該プログラムを任意の入力に対し走らせるのに必要とされる全ての情報が当該プログラムだけから分かるという点で”クリアな”プログラムである。実際、このプログラムは任意の可能な入力値(例えばa[]の値)に対し、配列 a[]の初めの10エントリーを配列 b[]の対応したロケーションに移すに過ぎないことは表1から明らかである。
表1のプログラムに相当するC言語プログラムは次の通りである。
main{
for(i=0;i<10;i++)
move(i);
}
void move(int
i){
b[i]=a[i];
}
表1のプログラムが分岐セパレータ102へ与えられれば、表2に示す保護プログラム及び表3に示す分岐テーブルが得られるであろう。
この保護プログラムを生成する際、命令の順番は維持できたであろうから、行番号は順序通りである。しかし、これら行番号が正しいとしたら、セキュリティチップ30に渡されるアドレスを解析すれば、どこでジャンプするか又はしないかが分かるであろう。例えば、表2の保護プログラムにおいて行番号が正しいならば、ジャンプアドレスnの要求の後にジャンプアドレスn+1の要求が続けば、アドレスnに関連したジャンプは起こらなかったことを意味する(さもなければn+1以外のジャンプアドレスが次のジャンプアドレスであろう)。この種の解析を防止するために、保護プログラムにおける行の順番がスクランブルされる。条件分岐毎に真と偽のアドレスが格納されるので、発生しないジャンプに続くコードは、そのジャンプの後に順番に続く必要はない。
図9乃至図13はクリアプログラムのより長い例のリスト(A)であり、図14乃至図21は同プログラムに対応した保護プログラムのリスト(B)であり、図22は同プログラムに対応した分岐テーブルである。図23乃至図25は分岐セパレータ(図3)をソフトウエアで実現するために用いられるプログラムのリスト(D)である。当該プログラムは、Unixオペレーティングシステムの走るコンピュータ上で一般に利用可能な”awk”言語で記述されている。一見して明らかなように、図14乃至図21のプログラムは図22の分岐テーブルを時折参照しないと実行できない。
実施例によっては、分岐セパレータ102は分岐テーブルを参照する間に実行されるいくつかの命令についてチッェクサムの計算も行う。これらのいくつかの命令は、分岐を全く含まないから毎回同じ順番で実行されるはずであり、したがって、そのチェックサムは計算が容易である。これらのチェックサムはチッェクサムデータ118として格納される。同じように、実施例によっては、それらのいくつかの命令のための実行時間を計算し、タイミングデータ120として格納することができる。
解析に対しより強固なセキュリティが必要とされるときには、分岐をセキュリティチップ30により実行させるのではなく、セキュリティチップ30で発生した分岐を実現するための割り込みを発生してもよい。こうすれば、模倣者は発生しない分岐は発見できないであろう。
保護プログラム114、分岐テーブル116、チェックサムデータ118及びタイミングデータ120が生成された後、この情報は必要ならば圧縮器104によって圧縮される。圧縮器104は例えば、Allen,Boliek及びBchwarzに対し付与された米国特許第5,381,145号”Method and Apparatus for Parallel Encoding and Decoding of Data”に示されているエントロピーコーダーである。圧縮は、一定サイズのROMにより多くのデータを格納できるようにするために利用されるだけではなく、データ中に現れるかもしれない何らかのパターンを除去することによって、キー無しでの復号をより一層困難にするためにも利用される。
暗号化器108はいくつかの形態をとり得る。ハードウエアコストを抑えることよりもセキュリティが優先される場合には、暗号化器108をデータセキュリティの分野で知られている標準暗号方式(DES)の暗号化器、トリプルDES暗号化器、あるいはさらに安全な暗号化システムとしてよい。ゲームが販売される国及びゲームが使用されると考える国の法律、並びに、セキュリティのニーズと計算能力の制約とのバランスに応じて、各種の暗号化器108が用いられてよい。暗号化プロセスのセキュリティの優先度がハードウエアコストを抑えることより低い場合には、いくつかの単純な暗号化回路を用いてもよい。一実施例では、暗号化は単にクリア(clear)データと疑似乱数発生器(PRNG)の出力ビットストリームとの排他的論理和(XOR)のプロセスである。別の実施例では、クリアデータの順番がPRNGの出力に基づき並べ替えられる。ハードウエアコストはその分増加するが、これら2つの方法を一緒に用いてもよい。
上記の単純な暗号化方法は、PRNGをわずかなゲートで容易に作ることができるので低コストである。シフトレジスタにより構成されるPRNGについては、例えば図8を見られたい。図7は、データスクランブラー106の内部構成の詳細ブロック図を示す。データスクランブラー106はいくつかのバッファを使うが、これらバッファが圧縮器104の一部として既に存在する場合には、バッファに関するコスト増加はゼロである。
もう一つの低コストの変形例では、暗号化は圧縮と組み合わされる。この変形例では、圧縮はエントロピー圧縮であり、使用すべき最適コードを決定するために確率予測値のテーブルを用いる。これらのテーブルのためのメモリはいずれにしても圧縮のために必要であるから、これらテーブルを暗号化に利用してもハードウエアコストは全く増加しない。これらのテーブルは、最初に又は圧縮プロセス中にキー値又はキー値をベースにした数値に応じて種を設定することにより、暗号化のために利用される。この暗号化方式によって得られる利点は、確率テーブルが確立する機会を持つまでは圧縮プロセスは必ずしも圧縮しようとするデータ中のパターンを除去しないため、暗号化プロセスに対する公知の単純文字攻撃(plaintext attack)を防ぐことである。キー値により確率テーブルを初期化すれば、圧縮プロセスをそれほど簡単には解析できない。
暗号化器108の出力は、暗号化され、そして恐らく圧縮された後に、暗号化ROM32に格納される。次に、ゲーム機10と暗号化ROM32を使うゲームカートリッジ12の動作を図1から図5を参照して説明する。図4及び図5は、その両方で、プロセッサ20とセキュリティチップ30がゲームプログラムの一部を安全に実行するために踏むステップを表しており、命令及び/又はデータの1つのページを要求することから始まる(ステップS1)。
実現の容易さのため、プログラムデータを個別的に圧縮されたデータセットに編成してよく、プロセッサ20はある圧縮データセットを指すポインタを指定することによって、あるいは最後にデコードされたページに基づき限定されたページの組より1つのページを単に選択することによって、1つのページを要求する。セキュリティを高めるため、各データセットをプログラムの暗号化時に割り当てられたランダムIDにより確認してもよい。
あるページに対する要求はバス14を介してバスユニット50へ送られ、バスユニット50はその要求が適切であるか演算ユニット72に問い合わせる(ステップS2)。演算ユニット72は、分岐テーブルを保持しているので、どの命令がプロセッサ20により要求されるべきか否かを容易に判断できる。この機能によって、模倣者がプログラム全体をクリアプログラムとしてアセンブルできるようするため、プロセッサ20を既知の順序でプログラムのそれぞれの、かつ、すべてのブロックを要求するように制御することができないようにする。要求が適切でないときには、演算ユニット72はプロセッサ20を停止させる(ステップS3)。また、演算ユニット72が他にいくつかの働きをしてもよい。キー値を消去したり、ROM32を消去したり、データを時間とともに劣化させたり、あるいは、それ以上の解析を挫折させるための他のステップ等である。実施例によっては、演算ユニット72は検出された攻撃に対し、模倣者がゲームプログラムのフローの推定に成功したならば、その推定したフローが制限されるようプログラムのフローを変更することで応酬する。例えば、演算ユニット72はプログラムフローをゲームのほんの初めの数段階に制限してしまう。
要求が適切であるときには、該当ページがROM32から取り出される(ステップS4)。これを行うために、要求はバスユニット50により処理されてトランスレータ52へ送られる。プロセッサ20により用いられるアドレスとROM32をアクセスするために用いられるアドレスが同一である場合には、トランスレータ52は不要である。表1及び表2から分かるように、これらアドレスは必ずしも一致しない。暗号化によりデータのアドレスが変わるときにも、アドレスの変換が必要である。要求されたページが格納されているROM32のアドレスが決まったならば、そのアドレスはバス54によりROM32又はキャッシュ60へ出力される。どちらにアドレスが出力された場合でも、要求されたデータが復号化器62に入力される。この返されたデータはプログラム命令かデータオブジェクトであろう。そのデータがプログラム命令ならば、分岐テーブルの対応したエントリーが、チッェックサム及びタイミング情報が使われるときにはそれとともに、該データに付加される。
復号化器62は、キーレジスタ64から与えられるキー値を用いてデータを復号化する。復号化器62は暗号化器108の逆装置であり、そのキー値はキーレジスタ110に格納されているキー値と等しいか、またはその逆数であり、そのいずれであるかは採用される暗号化の種類による。復号化されたデータは次に伸長器68により伸長される。これらのエレメントの目的とするところは、図3に示したデータブロック114,116,118,120のデータのセクションを復元することである。このデータは次に、保護プログラム(クリアROMデータ)と秘密データ(分岐テーブル、チェックサム、タイミングデータ)とに分けられる。この保護プログラムはバスユニット50を経てプロセッサ20へ戻され、秘密データは演算ユニット72へ渡される。演算ユニット72は、このデータをプライベートテーブル74に格納する(ステップS5)。バスユニット50はクリアプログラムである保護プログラムページをプロセッサ20へ送る(ステップS6)。前述のように、この保護プログラムページだけでは模倣者はゲームプログラムの動作を複製できない。
プロセッサ20はプログラムデータの1つのページを得たならば、当該ページ中の命令を取出す(ステップS7)。プロセッサ20は、命令を実行する前に、それが分岐命令であるかチェックする(ステップS8)。分岐命令でなければ、プロセッサ20はその命令を実行し(ステップS9)、ページ中にさらに命令があるかチェックする(ステップS10)。ほかに命令があるならばプロセッサ20は次の命令を取り出すが(ステップS7へ戻る)、ほかに命令がなければ、プロセッサ20はROM32に次のページを要求する(ステップS1へ戻る)。
他方、命令が分岐命令であるときには、プロセッサ20はそれを処理しないので、分岐要求がセキュリティチップ30へ送られる(ステップS11)。この分岐要求が不適切であるとステップS12で判定されたときには、演算ユニット72はプロセッサ20を停止させる(ステップS13)。要求が適切であるためには、その要求が予期されていなければならず、予期された時に発生しなければならず、またバスチェックサムが正しくなければならない。適切な分岐要求に対するセキュリティチップ30の応答は、プロセッサ20が分岐すべき先のアドレスである。勿論、条件付き分岐の場合、プロセッサ20は1つ又は複数の引数をセキュリティチップ30へ渡す必要があるであろうし、セキュリティチップ30は真アドレスと偽アドレスのいずれかを計算して返すであろう(ステップS14)。次に、セキュリティチップ30はそのアドレスをプロセッサ20へ渡し(ステップS15)、プロセッサ20はそのアドレスへジャンプし(ステップS16)、そのアドレスから命令を取り出す(ステップS7へループバックする)。このように、プロセッサ20にはどんな種類の分岐であるか、可能な分岐アドレスが何であるかは全く知らされずに、分岐のためのアドレスが与えられる。
演算ユニット72は分岐要求の処理と、分岐要求が適切であるか否かの評価の両方に利用される。これをするために、演算ユニット72はプライベートテーブル74の一部として格納されるプライベート分岐テーブルを利用する。この分岐テーブルは分岐全部を格納する必要はなく、やがて発生する分岐を格納するだけでよい。この分岐テーブルの分岐エントリー毎に、次に述べるフィールドが保持される。
TYPE − 分岐の種類で、次の中から選ばれる:
1)無条件ジャンプ
2)条件付きジャンプ
3)サブルーチンコール
4)サブルーチンリターン
CONDITION − 条件付きジャンプと共に用いられるだけであり、テストさ
れる条件を指示する。
ADDRESS 1 − 無条件ジャンプと真条件の無条件ジャンプの場合にはジャ
ンプ先のアドレスであり、コールの場合には呼び出されるアドレスであり
、リターンの場合には使用されない。
ADDRESS 2 − 無条件ジャンプには使用されない。偽条件の条件付きジャ
ンプの場合にはジャンプ先アドリスである。コールの場合にはリターンア
ドレスであり、スタックにセーブされる。リターンの場合には利用されな
い。
実施例によっては、プロセッサ20はやがて発生する分岐のための分岐テーブルのインデックスを指定もしないし、全く知らされもしない。そのような実施例においては、分岐テーブルは現在の分岐の後にどの分岐インデックスが続くべきかを記録している。勿論、次の分岐はどの分岐が起こっているかに応じて決まるので、そのような実施例においては、その情報が次に述べる2つのフィールドに格納される。
NEXT BRANCH 1 − プログラムコード中のADDRESS 1の後の
最初の分岐のインデックスを示す。
NEXT BRANCH 2 − プログラムコード中のADDRESS 2の後の
最初の分岐のインデックスを示す。
CHECKSUM − 分岐前の全てのプログラムコードに対し期待されるチェック
サムである。
EXECUTION TIME − 前の分岐から次の分岐までの期待される実行時
間である。
PASSWORD − 現在の分岐を実行するために必要とされるパスワードである
。
TYPEフィールドは分岐の種類を指示し、したがって他のどのフィールドが利用されるかをも指示する。例えば、無条件分岐(例えば“goto5”)のためのエントリーは、条件も偽条件アドレスも含む必要がない。勿論、システムによっては、条件コールや条件付きリターンのような他の分岐も可能である。高度なセキュリティシステムでは、NOP分岐もセキュアプログラムに含めてもよい。
CONDITIONフィールドは、変数と定数の比較のためにオペランドと定数で表現してよく(例えば”branch if(i>=10)”)、変数と変数の比較のためにオペランドだけで表現してよい(例えば”branch if(x<y)”)。比較のために変数が必要な場合、その変数はプロセッサ20により分岐要求の一部としてセキュリティチップ30へ渡される。プロセッサ20は、どの条件が適用されようとしているかについて通知される必要はなく、引数としてどの変数をいくつ渡すべきかを知らされるだけでよい。一実施例では、TYPEフィールドはどの種類の条件フィールドが使用されるかを指示し、VALUEフィールドは1が使用される場合に定数値を指示する。
ADDRESS1とADDRESS2のフィールドは、現在要求されている分岐のための次のアドレスを与える。条件付き分岐の場合、条件が真ならばADDRESS1が与えられ、さもなければADDRESS2が与えられる。無条件分岐の場合、ADDRESS2は使われない。コールの場合、ADDRESS1はコールされるアドレスでプロセッサ20へ与えられ、一方、ADDRESS2はコールの次の命令のアドレス(すなわちリターンアドレス)である。そのADDRESS2の値はスタックに置かれ、後に対応したリターン分岐に用いられる。リターンの場合、どのアドレスフィールドも用いられない。リターンアドレスはスタックより与えられるからである。
表2は、プロセッサ20のようなプロセッサにより実行されることを意図した保護プログラムを示す。プロセッサは、分岐要求(クリアプログラムの分岐に代わるもの)に到達すると、分岐要求を出し、分岐要求のインデックスを条件の評価のために必要な引数と一緒にセキュリティチップへ渡す。例えば、表2のアドレス4で、ある特定の分岐インデックスの分岐要求が出される。命令”br_req 1”は、分岐テーブルのエントリー1が用いられるべきであることを知らせる。しかし、確信犯的模倣者の中には、分岐要求のインデックスを分岐情報を抽出するために利用する者がいるかもしれない。例えば、そのような模倣者は、”br_req1”命令を十分追跡することにより、この命令がリターン命令に相当することを確認できるかもしれない。次々にインデックス付けされた分岐要求を解析することにより、各分岐の種類と条件を確認することができる。
この種の解析をさらに困難にするため、命令中のインデックスを除くことができる。命令”br_req1”と命令”br_req2”をプロセッサに利用できるようにするのではなく、これら命令は両方ともただ”br_req”として知らされる。索引情報はNEXT BRANCH 1フィールドとNEXT BRANCH 2フィールドに格納される。全ての分岐が演算ユニット72により制御されるから、現在の分岐のアドレスの次の分岐要求は分かっているため容易に格納される。NEXT BRANCH 1フィールドは、ADDRESS 2が発生した分岐の時に次の分岐のためのインデックスを含む。コールの場合、ADDRESS 1はコールされるサブルーチンの先頭であり、ADDRESS 2はコール命令の次の命令のアドレスである。したがって、NEXT BRANCH 1はサブルーチン中の最初の分岐のインデックスであり、NEXT BRANCH 2はADDRESS 2アドレスの次の最初の分岐のインデックスである。コールの場合、ADDRESS 2とNEXT ADDRESS 2は、演算ユニット72内のスタックにプッシュされる。
CHECK SUM,EXECUTION TIME及びPASSWARDのフィールドは、それらが用いられる場合には、分岐要求が許可されるか否かを判断するために用いられる。分岐の後で、バスタップからのバス情報が演算ユニット72へ送られ、演算ユニット72は分岐が見つかるまでバスデータのチェックサムをとる。その結果得られたチッェクサムは、格納されているCHECKSUMと比較される。これらチェックサムが相違する場合、演算ユニット72はゲームをそれ以上進行させない処置をする。チェックサムを、プロセッサバス上の全てのトラフィック(当然、変数データは除く)に対して適用できる。
同様に、リアルタイムクロック76を利用して分岐と分岐の間の時間が記録され、その時間はEXECUTION TIME値と比較される。途中に入り込む分岐はなく、分岐と分岐の間の命令数は分かっているので、プロセッサのクロックレートが分かっていれば期待される時間の長さは容易に決まる。また、別のリアルタイムクロックは必要でない。PRNGが復号化プロセスの一部として利用されるときには、PRNGを、それが利用されるか否かにかかわらず、各命令サイクルをクロックするように設定してよい。そのようにすれば、余分な命令が入り込むと、PRNGはデータと同期しなくなりデータを壊すことになろう。
格別に注意を要する分岐については、PASSWORD値を割り当ててよく、この場合にはプロセッサは、その分岐を発生させるためにはパスワードを与えなければならない。PASSWORD値は、プロセッサの状態とローカルメモリの記憶内容との既知の組合せから計算してもよい。
分岐処理をセキュリティチップに依存すると、プロセッサがクリアプログラムを処理する場合より時間がかかるかもしれない。コードの実行が時間的に厳しい場合、プログラムコードの選択したセクションに関する保護を働かなくさせてもよく、そうするとプロセッサ自体で分岐処理を行う。また、処理時間を減らすため、時間的に厳しいプログラムコードのために必要な処理の部分をセキュリティチップに実行させてもよい。
図6は上記ルールを実現するために用いられる、演算ユニット72の一部たる分岐ユニット500を示す。分岐ユニット500は分岐テーブル502から一つのエントリーを、バスタップ504からデータを、DATA
INバス506から引数を受け取り、これら入力に基づき、不適切な分岐が要求されたことを示すエラー信号又は適切に要求された分岐のアドレスを出力する。ある実施例では分岐アドレスはプロセッサ20へ渡されるが、別の実施例では分岐アドレスはプロセッサ20にどの命令が与えられるかを制御するために用いられ、それら命令のためのアドレスはプロセッサには全く知らせない。
分岐ユニット500の動作は以下のとおりである。分岐テーブル502のあるエントリーが選択されると、VALUE,TYPE,CHECKSUM,PASSWORD,TIMING,ADDRESS 1,ADDRESS 2,NEXT 1,NEXT 2のフィールドが出力される。VALUEフィールドは定数と比較する条件付きジャンプに関する定数であり、減算器508の一方の入力となる。減算器508の他方の入力は、DATA
INバスの最後の内容を保持するレジスタ510より与えられる。減算器508は可変引数と定数との比較の結果を出力し、場合によっては、一方の入力が他方の入力と比べ大きいか、等しいか、又は小さいかを示すだけである。減算器512は同様に、レジスタ512の出力と、それに接続されたもう一つのレジスタ514の出力とを比較する。これら両減算器の出力はコントロール部516へ与えられる。
コントロール部516は、エラー信号を出力すべきか否かを判断し、また2つのマルチプレクサ(MUX)518,520を制御する。MUX518の出力は分岐アドレスであり、これはADDRESS 1,ADDRESS 2,スタック522より与えられるスタックトップ値のいずれか一つより選ばれる。MUX520の出力は、NEXT 1,NEXT 2,初期値,スタックトップ値の中の一つである。MUX520の出力は、次の分岐のためのインデックスを示し、分岐テーブル502へインデックス入力としてフィードバックされる。初期値は、PENDING線を適切に初期化するために分岐連鎖中の最初の分岐を指すポインタである。
コントロール部516は、その入力に基づき、上に指摘したようにMUXのどの出力が有効であるか決定する。すなわち、分岐TYPEが無条件ジャンプ、コール、又は真条件の条件付きジャンプである時にはADDRESS 1が選択される。偽条件の条件付きジャンプの時にADDRESS 2が選択され、リターン分岐の時にスタックトップが選択される。コールの場合、ADDRESS 2はスタックにプッシュされ、次のリターンに用いられる。
コントロール部516はまた、MUX520のどの出力が有効であるか決定する。すなわち、分岐TYPEが無条件ジャンプ、コール、又は真条件の条件付きジャンプの時には、NEXT 1が選択されてPENDING線に与えられる。偽条件の条件ジャンプの時にはNEXT
2が選択され、リターン分岐の時にはスタックトップが選択される。
コントロール部516は、分岐テーブル502から与えられたCHECKSUM値が、チェックサムロジック524がバスタップ504より与えられた時に計算したものと一致しない場合、リアルタイムクロック76をモニタすることによって得られた実行時間がEXECUTION TIME(TIMING)フィールドにより指定された所期の実行時間と一致しない場合、又は、プロセッサ20により与えられたパスワードがPASSWORDフィールドと一致しない場合に、エラー信号を出力する。
図7はスクランブラー106を詳しく示す。スクランブラー106はデマルチプレクサ(DEMUX)602、MUX604、疑似乱数発生器(PRNG)606、いくつかのバッファ608からなる。3つのバッファ608A,608B,608Cが示されているが、バッファの数は3個に限らない。スクランブラー106の入力データストリームに対する働きは、入力データストリームのビット、バイト、ワード又はブロックの順序を決定論的かつ可逆的方法により並べ替えることである。
この並べ替えを行うために、DEMUX602は、その入力のデータエレメント(ビット、バイト、ワード又はブロック)を、その出力中の現在の疑似乱数により決まる1つの出力に送る。現在の疑似乱数が変わると、エレメントが送られ出力が変わる。MUX604はバッファにより出力された別々のエレメントストリームをまとめて1つのストリームにする。バッファ608の構成により、これらエレメントがDEMUX602とMUX604の間を移動するのに必要な時間が異なるため、これらエレメントは並べ替えられる。各バッファ608は、ヘッドとテールを交替する先入れ先出し(FIFO)バッファであるか、あるいは、後入れ先出し(LIFO)バッファとしてヘッドとテールを交替するFIFOバッファである。前者の場合には、あるバッファ608へ左から一つのエレメントがシフトインされる度に、そのバッファの右側から一つのエレメントがMUX604へ出力され、バッファへ右側から一つのエレメントがシフトインされる度に、左側から一つのエレメントが出力される。後者の場合には、エレメントはバッファに両側から入れられるが、それらエレメントが出力されるのは右端からである。エレメントがバッファ608のどちら側の端よりシフトインされるかは、PRNG606により出力される値によって制御される。
このように、疑似乱数シーケンスが分かれば、並べ替えのパターンの発見し、それをリバースすることが可能であろう。疑似乱数シーケンスを発見するためには、キー値(図2のキーレジスタ64又は図3のキーレジスタ110に格納されている)が分からなければならない。なぜなら、そのキー値はPRNG606の種として働くからである。勿論、ハードウエアが割高な場合には、スクランブラー106が伸長器の部分を利用してもよいし、あるいは内部の伸長テーブル、例えば確率予測テーブルやR−コードテーブルのスクランブル又は変更のためにキー値を用いてもよい。
ハードウエアロジックが特に割高な場合には、図8に示す疑似乱数発生器(PRNG)700を用いるとよい。PRNG700に必要なものは一つのキーシフトレジスタ702、一つの最大長シーケンス(MLS)シフトレジスタ704、2つのMUX706,708、それに一つのXORゲート710だけである。PRNG700に対する入力は、キークロック712、MLSクロック714、KEY
INシリアル入力、KEY LOAD信号及びINIT/RUN信号により与えられる。キーシフトレジスタ702は、一旦ロードされればキーレジスタ64又は110として利用でき、無停電電源716により給電される。
キーシフトレジスタ702の入力はMUX706の出力であるが、これはキーシフトレジスタ702のループバックされた出力であるかKEY IN入力のいずれかであり、そのどちらであるかは、MUX706のセレクト入力のKEY LOAD信号が付勢されたか否かにより決まることが図8から分かる。MLSシフトレジスタ704の入力はMUX708の出力であるが、これはキーシフトレジスタ702の出力であるかXORゲート710の出力であり、そのいずれであるかは、MUX708のセレクト入力のINIT/RUN信号がINITであるかRUNであるかにより決まることも図8から分かる。XORゲート710の入力は、MLSシフトレジスタ704の出力とMLSシフトレジスタ704の最終段以外の段からのタップである。使用されるタップとMLSシフトレジスタの段数によって、得られる疑似乱数シーケンスの長さが決まる。シーケンス長とタップ点の例については、Knuth,D.E.,The Art of Computer Program,2d.ed.,pp.27−29とそのTable1を参照されたい。一実施例では、MLSシフトレジスタ704の段数は98であり、キー値のビット数は98である。ただし、これ以外の長さ及びタップでも同じように動作する。勿論、キー値のビット数は模倣者がその値を簡単には推測できないよう十分大きくすべきである。98段のMLSシフトレジスタが送出するビットシーケンスは、298−1ビット毎に繰り返すだけである。このような多段数の場合、シフトレジスタは最大長である必要はない。レジスタを最大長にしないことの一つの利点は、最大長のシフトレジスタのためのタップのセットは当該分野で知られているので、非最大長のシフトレジスタの方がリバースエンジニアにとって面倒であろうという点である。
KEY LOAD信号を付勢し、KEY IN入力にキーを与え、キー値がロードされるまでキークロック712をクロッキングすることにより、キー値がキーシフトレジスタ702に初期ロードされる。キー値がロードされたならばKEY LOAD信号は消勢されるため、キークロック712のクロッキングによりキーシフトレジスタ702内のキー値が循環させられるだけである。KEY LOAD信号は消勢したままにすべきであるが、これはリーディング”1”ビットをキーの前に置くことにより行ってもよい。この場合、当該ビットはキーシフトレジスタ702の出力に達した時にフリップフロップ(不図示)をセットするために使われる。このフリップフロップによって、KEY LOAD信号が付勢され、また無停電電源716により給電されてよいか否かが制御されるであろう。
キー値は、それを読み出すためにキーシフトレジスタ内で循環させられる。INIT/RUN信号がINITに設定された時に、キー値は、キークロック714と一緒に刻時するMLSクロック714によってクロッキングされてMLSシフトレジスタ704に入力される。MLSシフトレジスタ704は、ロードされると、その内容を循環させるが、同内容はXORゲート710により変更され、当該技術分野において知られているように疑似乱数の最大長シーケンスを生成する。このシーケンスの疑似乱数はMLSシフトレジスタ704より並列に読み出すことができる。今述べたような低コストのPRNGによれば、多重キーの実現が容易になる。
要約すると、プログラムを走らせるために必要なハードウエア及び/又はソフトウエアのエンドユーザ部分にしかアクセスできない模倣者によるプログラムデータのコピーを防止するためのシステムについて以上に論じた。それら例は、ゲームカートリッジで提供されてゲーム機で利用されるゲームプログラムのプロテクトに関する特別な用途に関するものであったが、それ以外の用途についても述べた。さらに、プログラムが主としてソフトウエアとして与えられる場合でも、わずかなハードウエアコンポーネントが提供されさえすれば、本発明は利用可能である。しかし、本発明の従来技術より優れている点は、プログラムデータがセキュリティチップにより復号化されるまでは暗号化されたままであり、そしてまた、プロセッサに与えられるのはプログラムデータ全体の一部でしかない、すなわちユーザによって与えられた特定の入力セットに対しフローが決まるプログラムの具体的動作例を実行するためのプログラムコードしか利用可能にならない、ということである。プロセッサに与えられなかったデータは、そのプログラムデータをプロセッサが要求するのに適切なタイミングであると分かった時点でだけプロセッサに与えられるか、あるいは全く与えられない。後者の場合、セキュリティチップが、プログラムデータ全部を与えられたならばプロセッサによりなされるであろう動作を実行する。一実施例では、セキュリティタップに保有される情報は分岐情報である。したがって、プロセッサが分岐命令に出会った時には、セキュリティチップの支援がないとその命令を完了できない。
また以上の記述において、セキュリティチップの内部構造及び動作、暗号化プログラムデータを生成するためのシステム、通常動作中及び模倣者からの攻撃にさらされた動作中におけるセキュリティチップとプロセッサとの相互動作、並びに格納されたキー値に基づいた低コストの疑似乱数発生器について説明した。
しかし、以上に述べたことは説明のためのものであって、限定することを意図したものではない。ここに開示する内容を検討すれば、当業者には本発明の多くの変形が明らかになろう。一例にすぎないが、以上の説明において、ビデオゲームを違法な複製と使用から保護する本発明の実施例を述べたが、ここに開示したことから本発明のゲーム以外への応用は理解されよう。その他の変形を以下に述べる。
本発明によるビデオゲームのある実施例においては、プレーヤーが残した”生命”数と、プレーヤーが次の段階へ進むまでの残時間の長さをセキュリティチップが監視する。セキュリティチップは、プログラムデータを一度に1レベルずつ復号化するので、最初はゲームの第1レベルのためのプログラムデータしか復号化しない。プログラムデータは初期値を含んでいるが、これらの初期値はセキュリティチップの外部に明示されることは決してないもので、当該レベルのためのタイマーを設定するために用いられる。プレイヤーがゲームをプレイしている時に、プログラムは一定の事象が生じたことをセキュリティチップに知らせる。プロセッサからの情報が期待通りであれば、ゲームは正常にプレイされる。しかし、その情報が期待通りでない場合には、タイマーに時間が加算されるか、又は
”生命”が除かれる。タイマーの時間が増えると、プレイヤーは次のレベルへ達するために待たなければならない時間が増加する。この時間が、プログラムが意図したところと異なった動作をすることによりしばしば十分に増加すると、タイマーは決して時間切れにならないので、プレイヤーは第1レベルにいつづけることになる。この方法がセキュリティチップで単にプロセッサを遮断する方法に比べて有利な点は、プログラムのどこでセキュリティチップが最初に問題を検出したかはっきりしないことである。
前者の方法は、有利な点がないわけではない。プロセッサが誤り許容(fault-tolernat)システムの一部であるときには、それが模倣者の攻撃を受けやすいか否かにかかわらず、プロセッサが誤りを起こした後にそのプロセッサに動作を続けさせないための手段としてセキュリティチップを利用できる。同じセキュリティチップを、不適切な実行が検知された時にプロセッサを停止させあるいは警告を発生させるために用いることができるが、その予期しない動作がハードウエア又はソフトウエアにより引き起こされ、模倣者が故意に行ったことが原因ではないことが前提である。
ゲーム以外への利用例として、プロセッサは画像処理を行うかもしれない。画像処理では、たたみ込みが必要となろう。たたみ込みは多数の乗算と一つの加算の連続として行われる。セキュリティチップは、プロセッサのデータバスをモニターできるので、乗算結果がバス上に現れた時に加算を実行することができる。その和が必要な時には、プロセッサはそれをセキュリティチップに要求する。セキュリティチップなしでプロセッサを動作させると、たたみ込みを間違うか、あるいは、プロセッサ自体で累積を行わなければならないためプロセッサの動作が遅くなるであろう。
プログラムデータが圧縮される場合には、伸長器のエレメントを復号化処理に利用してもよい。例えば、図7は伸長器のバッファを用いて構成し得るデータスクランブラーを示す。また、伸長器がエントロピーエンコーダーの場合、セキュリティチップはキー値を伸長処理のための初期パラメータ、例えば初期確率値を生成するために利用してよい。こうすると、エントロピーコーダーのスタート時、ビットそのものから確率を推定できるだけのビットが得られる前に起きやすい1対1変換を防ぐというもう一つの利点が得られる。
セキュリティチップは、セキュリティ侵害を検出した時にプロセッサを停止させるにおよばない。他の選択肢は、ランダムな時間だけ遅延させた後にプロセッサをリセットすること、疑似乱数をデコードデータとして出力すること、あるいは、PRNGが出力中のデータを徐々に低下させるようにコンプリメントイネーブリング(complement enabling)または他の方法によりPRNGを調整することである。