Friday, 30 August 2013

C++/CLI marshalingl/aliasing of memory and struct intropbability

C++/CLI marshalingl/aliasing of memory and struct intropbability

I've wrapped Christophe Devine's FIPS-197 compliant AES implementation in
a managed C++/CLI class. I'm running into trouble after
encrypting/decrypting anywhere from 20 to 52 blocks of 4096 bytes each.
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::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::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.
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), 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 overallocate I get the same result.
I'm using the Visual Studio 2012 C++ compiler.
Anyone know anything that might suggest why this is the case?

No comments:

Post a Comment