我将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 ++编译器。
有谁知道任何可能暗示为什么会出现这种情况的事情?
答案 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
是一个固定指针,以便永久固定它,而不是暂时固定它,因为每次调用都会使程序成功运行。