- Home /
Crash on a stripped iOS binary when using System.Security.Cryptography
Hi,
The game I'm working on uses several classes from the System.Security.Cryptography package. If I run it on a normal build it works perfectly, but if I try to strip it using either StrippingLevel.StripAssemblies or StrippingLevel.StripByteCode stripping levels, it crashes with a EXC_BAD_ACCESS.
Here is the mono code that crashes :
PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(ENCODING_KEY, new byte[] {some bytes...});
Rijndael alg = Rijndael.Create();
alg.Key = passwordDeriveBytes.GetBytes(32);
alg.IV = passwordDeriveBytes.GetBytes(16);
Here is the assembly code that crashes (on the last '.byte' line) :
System_Security_Cryptography_PasswordDeriveBytes_Reset:
.byte 13,192,160,225,128,64,45,233,13,112,160,225,0,93,45,233,20,208,77,226,13,176,160,225,0,160,160,225,0,0,160,227
.byte 24,0,138,229,0,0,160,227,40,0,138,229,0,0,160,227,44,0,138,229,8,0,154,229
bl p_209
.byte 20,0,138,229,12,0,154,229,0,0,80,227,28,0,0,10,20,192,154,229,28,16,154,229,1,0,160,225,12,48,144,229
.byte 28,0,154,229,12,32,160,225,8,32,139,229,0,32,160,227,0,0,141,229,0,0,160,227,4,0,141,229,8,0,155,229
.byte 0,224,156,229
bl Lm_1803
Here is the end of the stack when the application crashes :
#0 0x0040311c in System_Security_Cryptography_PasswordDeriveBytes_Reset at /Users/me/projects/MyGame/iOS/Libraries/mscorlib.dll.s:131226
#1 0x00402df0 in System_Security_Cryptography_PasswordDeriveBytes_GetBytes_int at /Users/me/projects/MyGame/iOS/Libraries/mscorlib.dll.s:131153
So it seems both the PasswordDeriveBytes and Rijndael instances have been created, but that the first (probably) call to GetBytes calls an inner function Reset that is actually causing the crash.
Looking at the IL code of the aforementioned classes, I extracted all dependencies to other classes and added them to the following link.xml file that I put into project's Resources folder (just to be sure and despite the fact they are all present in the assembly source) :
<linker>
<assembly fullname="mscorlib">
<type fullname="System.Security.Cryptography.CipherMode" preseve="all"/>
<type fullname="System.Security.Cryptography.CryptoConfig" preseve="all"/>
<type fullname="System.Security.Cryptography.CryptoStream" preseve="all"/>
<type fullname="System.Security.Cryptography.CryptoStreamMode" preseve="all"/>
<type fullname="System.Security.Cryptography.CryptographicException" preseve="all"/>
<type fullname="System.Security.Cryptography.CryptographicUnexpectedOperationException" preseve="all"/>
<type fullname="System.Security.Cryptography.CspParameters" preseve="all"/>
<type fullname="System.Security.Cryptography.DeriveBytes" preseve="all"/>
<type fullname="System.Security.Cryptography.HashAlgorithm" preseve="all"/>
<type fullname="System.Security.Cryptography.ICryptoTransform" preseve="all"/>
<type fullname="System.Security.Cryptography.KeySizes" preseve="all"/>
<type fullname="System.Security.Cryptography.PaddingMode" preseve="all"/>
<type fullname="System.Security.Cryptography.PasswordDeriveBytes" preseve="all"/>
<type fullname="System.Security.Cryptography.Rijndael" preseve="all"/>
<type fullname="System.Security.Cryptography.SHA1" preseve="all"/>
<type fullname="System.Security.Cryptography.SHA1CryptoServiceProvider" preseve="all"/>
<type fullname="System.Security.Cryptography.SymmetricAlgorithm" preseve="all"/>
</assembly>
</linker>
And, to be even more complete, I also tried :
<linker>
<assembly fullname="mscorlib">
<type fullname="System.Security.Cryptography" preseve="all"/>
</assembly>
</linker>
... but the application continues to crash. Off course, if I stop using those classes, the game works perfectly well, just lacking some features !
Edit : As a side note, I use the SHA256Managed class somewhere else in the code, which is also in the System.Security.Cryptography package, and it works perfectly well, so the problem seems tied to the PasswordDeriveBytes class or one of the class it uses...
Does anyone have any idea on what I am missing ?
Hello how did you solve this problem? I run into the same issue. Thanks.
We searched for the exact cryptography class that was causing the problem by successively deactivating whole portions of code until the game stops crashing. Then we stopped using that class, replacing it by our own implementation of it.
Unfortunately, I don't remember what class it was, probably a Rijndael related one.
Answer by cpx_matthew · Apr 23, 2013 at 05:51 AM
Avoid the call to Rijndael.Create();
which uses dynamic providers and reflection and instead directly use a concrete provider.
For example, I fixed Uniweb Websockets on iOS AOT by replacing
var sha = System.Security.Cryptography.SHA1.Create ();
with
var sha = new System.Security.Cryptography.SHA1CryptoServiceProvider ();
This looks to be fixed in Mono 3.0.2. Commit notes:
Make the Crypto stack work with Full AOT.
* System.Security.Cryptography.*cs: To make Crypto work with
Full AOT we remove the usage of providers and reflection. We hardcode
the default algorithms for hashing, rng and symmetric cyphers.
Answer by nah0y · Jul 01, 2013 at 12:30 PM
Same thing here, the correct syntax working for me is :
<linker>
<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all" />
</assembly>
</linker>
Your answer
Follow this Question
Related Questions
[URGENT] OpenFeint integration problems 0 Answers
Tracking down a SIGABRT on startup 8 Answers
Does Unity have any symmetric crypto libraries? 1 Answer
Program Recieved Signal: 0 1 Answer