[英]C++/CLI marshalling/aliasing of memory and struct interoperability
I've wrapped Christophe Devine's FIPS-197 compliant AES implementation in a managed C++/CLI class. 我将克里斯托弗·迪瓦恩(Christophe Devine)的FIPS-197兼容AES实现包装在托管C ++ / CLI类中。 I'm running into trouble after encrypting/decrypting anywhere from 20 to 52 blocks of 4096 bytes each.
在从20到52个块(每个4096字节)的任何地方进行加密/解密后,我遇到了麻烦。 I've been able to narrow the issue down to this:
我已经能够将问题缩小为:
If I declare a native pointer to the aes_context
struct and just new up the aes_context
in the constructor, like so 如果我声明一个指向
aes_context
结构的本机指针,然后在aes_context
函数中重新aes_context
,就像这样
Aes::Aes()
: m_Context(new aes_context)
{
}
Then the code will run fine. 然后代码将正常运行。
But when I attempt to declare the aes_context
as array<System::Byte>^
and then in the constructor do this 但是当我尝试将
aes_context
声明为array<System::Byte>^
然后在构造函数中执行此操作
Aes::Aes()
: m_Context(gcnew array<System::Byte>(sizeof(aes_context)))
{
}
While it does compile and in theory should work, this now doesn't 尽管它确实可以编译并且理论上应该可以工作,但现在不行了
pin_ptr<System::Byte> pinned_context = &m_Context[0];
auto context = (aes_context*)pinned_context;
aes_crypt_cbc(context, ...);
Effectively and in my limited experience, this should work just fine. 根据我有限的经验,这应该有效。 The only difference is that the memory was allocated by the GC and that I have to pin the memory before I pass it to the AES library.
唯一的区别是内存是由GC分配的,在将内存传递给AES库之前,我必须固定内存。 I should also clarify that this is an error that happens at run-time not a compiler error.
我还应该澄清,这是在运行时发生的错误,而不是编译器错误。
I was unable to reproduce this issue any other way and all tests that I have run against other reference implementation doesn't reveal any issues with implementation. 我无法以其他任何方式重现此问题,并且针对其他参考实现运行的所有测试都没有揭示实现的任何问题。 I've even set up two exactly identical test cases, one in C and one in C++/CLI (that uses the managed wrapper to call into the AES library);
我什至设置了两个完全相同的测试用例,一个在C中,一个在C ++ / CLI中(使用托管包装器调用AES库)。 the managed wrapper doesn't work when backed by a managed byte array !?
由托管字节数组支持时,托管包装器不起作用!
Since the problem doesn't reveal itself after you've run through a fair deal of data, I've been thinking it's a truncation or alignment issue, but regardless of how much I over-allocate I get the same result. 由于在处理完大量数据后问题仍然无法解决,所以我一直认为这是一个截断或对齐问题,但是无论我分配了多少,都可以得到相同的结果。
I'm using the Visual Studio 2012 C++ compiler. 我正在使用Visual Studio 2012 C ++编译器。
Does anyone know anything that might suggest why this is the case? 有谁知道可能暗示这种情况的信息?
Not sure it's the only problem, but aes_context
is declared to contain a pointer, rk
; 不确定这是唯一的问题,但是
aes_context
被声明为包含指针rk
;
typedef struct
{
int nr; /*!< number of rounds */
unsigned long *rk; /*!< AES round keys */
unsigned long buf[68]; /*!< unaligned data */
}
aes_context;
...that is set by (for example) aes_setkey_enc
to point to an address insinde buf
inside the same context; ...(例如,由
aes_setkey_enc
为指向同一上下文中的insinde buf
地址);
ctx->rk = RK = ctx->buf;
If - between that pointer set and your pinning the pointer - the context memory block is moved in memory, ctx->rk will point to unallocated memory. 如果-在该指针集和您固定指针之间-上下文存储块在内存中移动,ctx-> rk将指向未分配的内存。
I suspect making m_Context
a pinned pointer to keep it permanently pinned instead of pinning it temporarily for each call would make the program run successfully. 我怀疑将
m_Context
为固定指针以使其永久固定,而不是在每次调用时将其临时固定都会使程序成功运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.