简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM