C ++ / CLI编组/别名内存和结构互操作性

时间:2013-08-31 04:35:00

标签: c c++-cli aes

我将Christophe Devine的FIPS-197 compliant AES implementation包装在托管的C ++ / CLI类中。加密/解密后,我遇到了麻烦,每个块有20到52个块,每个块有4096个字节。我已经能够将问题缩小到这个范围:

如果我声明了一个指向aes_context结构的本地指针,并且只是在构造函数中新建aes_context,那么

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

然后代码运行正常。

但是当我尝试将aes_context声明为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库之前固定内存。我还应该澄清,这是在运行时发生的错误,而不是编译器错误。

我无法以任何其他方式重现此问题,并且我针对其他参考实现运行的所有测试都没有发现任何实现问题。我甚至设置了两个完全相同的测试用例,一个用C语言,一个用C ++ / CLI(用托管包装器调用AES库);托管的字节数组支持时,托管包装器不起作用!?

由于问题在你经历了大量数据之后并没有显现出来,我一直认为这是一个截断或对齐问题,但无论我过度分配多少,我都得到相同的结果。

我正在使用Visual Studio 2012 C ++编译器。

有谁知道任何可能暗示为什么会出现这种情况的事情?

1 个答案:

答案 0 :(得分: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-&gt; rk将指向未分配的内存。

我怀疑m_Context是一个固定指针,以便永久固定它,而不是暂时固定它,因为每次调用都会使程序成功运行。