2

Christophe Devine のFIPS-197 準拠の AES 実装をマネージ C++/CLI クラスにラップしました。それぞれ 4096 バイトの 20 から 52 ブロックを暗号化/復号化した後、問題が発生しました。問題を次のように絞り込むことができました。

構造体へのネイティブポインターを宣言し、コンストラクターでaes_context新しいものを作成すると、次aes_contextのようになります

Aes::Aes()
    : m_Context(new aes_context)
{
}

その後、コードは正常に実行されます。

しかし、aes_contextasを宣言しようとするarray<System::Byte>^と、コンストラクターでこれを行います

Aes::Aes()
    : m_Context(gcnew array<System::Byte>(sizeof(aes_context)))
{
}

コンパイルされ、理論上は動作するはずですが、現在は動作しません

pin_ptr<System::Byte> pinned_context = &m_Context[0];
auto context = (aes_context*)pinned_context;
aes_crypt_cbc(context, ...);

効果的に、そして私の限られた経験では、これはうまくいくはずです。唯一の違いは、メモリが GC によって割り当てられたことと、AES ライブラリに渡す前にメモリを固定する必要があることです。また、これはコンパイラ エラーではなく、実行時に発生するエラーであることも明確にする必要があります。

この問題を他の方法で再現することはできませんでした。他の参照実装に対して実行したすべてのテストでは、実装に関する問題は明らかになりませんでした。まったく同じ 2 つのテスト ケースを設定しました。1 つは C で、もう 1 つは C++/CLI (マネージ ラッパーを使用して AES ライブラリを呼び出します) です。マネージバイト配列でサポートされている場合、マネージ ラッパーは機能しません!?

かなりの量のデータを実行した後、問題は明らかにならないので、切り捨てまたは配置の問題だと考えていましたが、どれだけ過剰に割り当てても同じ結果が得られます.

Visual Studio 2012 C++ コンパイラを使用しています。

これが事実である理由を示唆する何かを誰かが知っていますか?

4

1 に答える 1

3

それが唯一の問題かどうかはわかりませんaes_contextが、ポインターを含むと宣言されていますrk

typedef struct
{
    int nr;                     /*!<  number of rounds  */
    unsigned long *rk;          /*!<  AES round keys    */
    unsigned long buf[68];      /*!<  unaligned data    */
}
aes_context;

...これは、(たとえば)同じコンテキスト内のaes_setkey_encアドレスを指すように設定されています。buf

ctx->rk = RK = ctx->buf;

そのポインタ セットとポインタの固定の間に、コンテキスト メモリ ブロックがメモリ内で移動された場合、ctx->rk は割り当てられていないメモリを指します。

m_Context呼び出しごとに一時的にピン留めするのではなく、ピン留めされたポインターを作成して永続的にピン留めすると、プログラムが正常に実行されると思われます。

于 2013-08-31T05:03:16.550 に答える