#include mobile_Mono.Security.dll.sources
+../corlib/CommonCrypto/CommonCrypto.cs
+../corlib/CommonCrypto/RC4CommonCrypto.cs
+../corlib/CommonCrypto/MD2Managed.g.cs
+../corlib/CommonCrypto/MD4Managed.g.cs
+../corlib/CommonCrypto/SHA224Managed.g.cs
+++ /dev/null
-./Mono.Security.Cryptography/ARC4Managed.cs
-./Mono.Security.Cryptography/MD2Managed.cs
-./Mono.Security.Cryptography/MD4Managed.cs
-./Mono.Security.Cryptography/SHA224Managed.cs
#include monotouch_Mono.Security.dll.sources
+../corlib/CommonCrypto/CommonCrypto.cs
+../corlib/CommonCrypto/RC4CommonCrypto.cs
+../corlib/CommonCrypto/MD2Managed.g.cs
+../corlib/CommonCrypto/MD4Managed.g.cs
+../corlib/CommonCrypto/SHA224Managed.g.cs
+++ /dev/null
-./Mono.Security.Cryptography/ARC4Managed.cs
-./Mono.Security.Cryptography/MD2Managed.cs
-./Mono.Security.Cryptography/MD4Managed.cs
-./Mono.Security.Cryptography/SHA224Managed.cs
#include common_System.Core.dll.sources
#include interpreter_System.Core.dll.sources
+../corlib/CommonCrypto/AesManaged.g.cs
+../corlib/CommonCrypto/AesCryptoServiceProvider.g.cs
#include common_System.Core.dll.sources
#include dynamic_System.Core.dll.sources
-
+../corlib/CommonCrypto/AesManaged.g.cs
+../corlib/CommonCrypto/AesCryptoServiceProvider.g.cs
--- /dev/null
+*.g.cs
+generator.exe
--- /dev/null
+// CommonCrypto bindings for MonoMac and MonoTouch
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012-2014 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+using System.Runtime.InteropServices;
+
+namespace Crimson.CommonCrypto {
+
+ // int32_t -> CommonCryptor.h
+ enum CCCryptorStatus {
+ Success = 0,
+ ParamError = -4300,
+ BufferTooSmall = -4301,
+ MemoryFailure = -4302,
+ AlignmentError = -4303,
+ DecodeError = -4304,
+ Unimplemented = -4305
+ }
+
+ // uint32_t -> CommonCryptor.h
+ // note: not exposed publicly so it can stay signed
+ enum CCOperation {
+ Encrypt = 0,
+ Decrypt,
+ }
+
+ // uint32_t -> CommonCryptor.h
+ // note: not exposed publicly so it can stay signed
+ enum CCAlgorithm {
+ AES128 = 0,
+ DES,
+ TripleDES,
+ CAST,
+ RC4,
+ RC2,
+ Blowfish
+ }
+
+ // uint32_t -> CommonCryptor.h
+ // note: not exposed publicly so it can stay signed
+ [Flags]
+ enum CCOptions {
+ None = 0,
+ PKCS7Padding = 1,
+ ECBMode = 2
+ }
+
+ static class Cryptor {
+
+ const string libSystem = "/usr/lib/libSystem.dylib";
+
+ // size_t was changed to IntPtr for 32/64 bits size difference - even if mono is (moslty) used in 32bits only on OSX today
+ // not using `nint` to be able to resue this outside (if needed)
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorCreate (CCOperation op, CCAlgorithm alg, CCOptions options, /* const void* */ byte[] key, /* size_t */ IntPtr keyLength, /* const void* */ byte[] iv, /* CCCryptorRef* */ ref IntPtr cryptorRef);
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorRelease (/* CCCryptorRef */ IntPtr cryptorRef);
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorUpdate (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ byte[] dataIn, /* size_t */ IntPtr dataInLength, /* void* */ byte[] dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved);
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorUpdate (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ IntPtr dataIn, /* size_t */ IntPtr dataInLength, /* void* */ IntPtr dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved);
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorFinal (/* CCCryptorRef */ IntPtr cryptorRef, /* void* */ byte[] dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved);
+
+ [DllImport (libSystem)]
+ extern internal static int CCCryptorGetOutputLength (/* CCCryptorRef */ IntPtr cryptorRef, /* size_t */ IntPtr inputLength, bool final);
+
+ [DllImport (libSystem)]
+ extern internal static CCCryptorStatus CCCryptorReset (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ IntPtr iv);
+
+ // helper method to reduce the amount of generate code for each cipher algorithm
+ static internal IntPtr Create (CCOperation operation, CCAlgorithm algorithm, CCOptions options, byte[] key, byte[] iv)
+ {
+ if (key == null)
+ throw new CryptographicException ("A null key was provided");
+
+ // unlike the .NET framework CommonCrypto does not support two-keys triple-des (128 bits) ref: #6967
+ if ((algorithm == CCAlgorithm.TripleDES) && (key.Length == 16)) {
+ byte[] key3 = new byte [24];
+ Buffer.BlockCopy (key, 0, key3, 0, 16);
+ Buffer.BlockCopy (key, 0, key3, 16, 8);
+ key = key3;
+ }
+
+ IntPtr cryptor = IntPtr.Zero;
+ CCCryptorStatus status = Cryptor.CCCryptorCreate (operation, algorithm, options, key, (IntPtr) key.Length, iv, ref cryptor);
+ if (status != CCCryptorStatus.Success)
+ throw new CryptographicUnexpectedOperationException ();
+ return cryptor;
+ }
+
+ // size_t was changed to IntPtr for 32/64 bits size difference - even if mono is (moslty) used in 32bits only on OSX today
+ [DllImport ("/System/Library/Frameworks/Security.framework/Security")]
+ extern internal static /* int */ int SecRandomCopyBytes (/* SecRandomRef */ IntPtr rnd, /* size_t */ IntPtr count, /* uint8_t* */ byte[] bytes);
+
+ static internal void GetRandom (byte[] buffer)
+ {
+ if (SecRandomCopyBytes (IntPtr.Zero, (IntPtr) buffer.Length, buffer) != 0)
+ throw new CryptographicException (Marshal.GetLastWin32Error ()); // errno
+ }
+ }
+
+#if !MONOTOUCH && !XAMMAC
+ static class KeyBuilder {
+ static public byte[] Key (int size)
+ {
+ byte[] buffer = new byte [size];
+ Cryptor.GetRandom (buffer);
+ return buffer;
+ }
+
+ static public byte[] IV (int size)
+ {
+ byte[] buffer = new byte [size];
+ Cryptor.GetRandom (buffer);
+ return buffer;
+ }
+ }
+#endif
+}
--- /dev/null
+//
+// CommonCrypto code generator for symmetric block cipher algorithms
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012 Xamarin Inc.
+//
+
+using System;
+using System.IO;
+
+namespace Xamarin {
+
+ public static class CommonCryptor {
+
+ static public void Generate (string namespaceName, string typeName, string baseTypeName, string ccAlgorithmName, string feedbackSize = "8", string ctorInitializers = null)
+ {
+ string template = @"// Generated file to bind CommonCrypto cipher algorithms - DO NOT EDIT
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012-2014 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+
+using Mono.Security.Cryptography;
+using Crimson.CommonCrypto;
+
+namespace %NAMESPACE% {
+
+ public sealed partial class %TYPE% : %BASE% {
+
+ public %TYPE% ()
+ {
+ FeedbackSizeValue = %FEEDBACKSIZE%;
+ %CTOR_INIT%
+ }
+
+ public override void GenerateIV ()
+ {
+ IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
+ }
+
+ public override void GenerateKey ()
+ {
+ KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+ }
+
+ public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ IntPtr decryptor = IntPtr.Zero;
+ switch (Mode) {
+ case CipherMode.CBC:
+ decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.None, rgbKey, rgbIV);
+ return new FastCryptorTransform (decryptor, this, false, rgbIV);
+ case CipherMode.ECB:
+ decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new FastCryptorTransform (decryptor, this, false, rgbIV);
+ case CipherMode.CFB:
+#if MONOTOUCH || XAMMAC
+ IntPtr encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV);
+ decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new CryptorTransform (decryptor, encryptor, this, false, rgbIV);
+#else
+ throw new CryptographicException (""CFB is not supported by Crimson.CommonCrypto"");
+#endif
+ default:
+ throw new CryptographicException (String.Format (""{0} is not supported by the .NET framework"", Mode));
+ }
+ }
+
+ public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ IntPtr encryptor = IntPtr.Zero;
+ switch (Mode) {
+ case CipherMode.CBC:
+ encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.None, rgbKey, rgbIV);
+ return new FastCryptorTransform (encryptor, this, true, rgbIV);
+ case CipherMode.ECB:
+ encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new FastCryptorTransform (encryptor, this, true, rgbIV);
+ case CipherMode.CFB:
+#if MONOTOUCH || XAMMAC
+ encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new CryptorTransform (encryptor, IntPtr.Zero, this, true, rgbIV);
+#else
+ throw new CryptographicException (""CFB is not supported by Crimson.CommonCrypto"");
+#endif
+ default:
+ throw new CryptographicException (String.Format (""{0} is not supported by the .NET framework"", Mode));
+ }
+ }
+ }
+}";
+
+ File.WriteAllText (typeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName).
+ Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).Replace("%FEEDBACKSIZE%", feedbackSize).Replace ("%CTOR_INIT%", ctorInitializers).
+ Replace ("%CCALGORITHM%", ccAlgorithmName.ToString ()));
+ }
+ }
+}
--- /dev/null
+//
+// CommonCrypto code generator for digest algorithms
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012-2014 Xamarin Inc.
+//
+
+using System;
+using System.IO;
+
+namespace Xamarin {
+
+ public static class CommonDigest {
+
+#if !MONOTOUCH && !XAMMAC
+ // we do not add anything in MonoTouch, just replacing, so this is not needed
+ // however we can avoid a dependency on Mono.Security for Crimson.CommonCrypto.dll by including the base classes
+ static public void GenerateBaseClass (string namespaceName, string typeName, string baseTypeName, int hashSize,
+ string visibilityStart = "", string visibilityEnd = "")
+ {
+ string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012-2014 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+using System.Runtime.InteropServices;
+
+namespace %NAMESPACE% {
+
+%VISIBILITY_START%
+ public
+%VISIBILITY_END%
+ abstract class %BASE% : HashAlgorithm {
+
+ protected %BASE% ()
+ {
+ HashSizeValue = %HASHSIZE%;
+ }
+
+ public static new %BASE% Create ()
+ {
+ return Create (""%BASE%"");
+ }
+
+ public static new %BASE% Create (string hashName)
+ {
+ object o = CryptoConfig.CreateFromName (hashName);
+ return (%BASE%) o ?? new %TYPE% ();
+ }
+ }
+}";
+
+ File.WriteAllText (baseTypeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName).
+ Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).
+ Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd).
+ Replace ("%HASHSIZE%", hashSize.ToString ()));
+ }
+#endif
+ static public void Generate (string namespaceName, string typeName, string baseTypeName, int contextSize,
+ string visibilityStart = "", string visibilityEnd = "")
+ {
+ string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2011-2014 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+using System.Runtime.InteropServices;
+
+using Mono.Security.Cryptography;
+
+namespace %NAMESPACE% {
+
+%VISIBILITY_START%
+ public
+%VISIBILITY_END%
+ sealed class %TYPE% : %BASE% {
+
+ IntPtr ctx;
+
+ [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Init"")]
+ static extern int Init (/* CC_%BASE%_CTX */ IntPtr c);
+
+ [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Update"")]
+ static extern int Update (/* CC_%BASE%_CTX */ IntPtr c, /* const void * */ IntPtr data, /* uint32_t */ uint len);
+
+ [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Final"")]
+ static extern int Final (/* unsigned char * */ byte [] md, /* CC_%BASE%_CTX */ IntPtr c);
+
+ public %TYPE% ()
+ {
+ ctx = IntPtr.Zero;
+ }
+
+ ~%TYPE% ()
+ {
+ Dispose (false);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (ctx != IntPtr.Zero) {
+ Marshal.FreeHGlobal (ctx);
+ ctx = IntPtr.Zero;
+ }
+ base.Dispose (disposing);
+ GC.SuppressFinalize (this);
+ }
+
+ public override void Initialize ()
+ {
+ if (ctx == IntPtr.Zero)
+ ctx = Marshal.AllocHGlobal (%CTX_SIZE%);
+
+ int hr = Init (ctx);
+ if (hr != 1)
+ throw new CryptographicException (hr);
+ }
+
+ protected override void HashCore (byte[] data, int start, int length)
+ {
+ if (ctx == IntPtr.Zero)
+ Initialize ();
+
+ if (data.Length == 0)
+ return;
+
+ unsafe {
+ fixed (byte* p = &data [0]) {
+ int hr = Update (ctx, (IntPtr) (p + start), (uint) length);
+ if (hr != 1)
+ throw new CryptographicException (hr);
+ }
+ }
+ }
+
+ protected override byte[] HashFinal ()
+ {
+ if (ctx == IntPtr.Zero)
+ Initialize ();
+
+ byte[] data = new byte [HashSize >> 3];
+ int hr = Final (data, ctx);
+ if (hr != 1)
+ throw new CryptographicException (hr);
+
+ return data;
+ }
+ }
+}";
+
+ File.WriteAllText (typeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName).
+ Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).
+ Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd).
+ Replace ("%CTX_SIZE%", contextSize.ToString ()));
+ }
+ }
+}
--- /dev/null
+//
+// CorlibExtras.cs: additional stuff not provided by autogenerated code
+//
+// Authors:
+// Sebastien Pouliot (sebastien@xamarun.com)
+//
+// Copyright (C) 2012 Xamarin Inc. All rights reserved.
+//
+
+namespace System.Security.Cryptography {
+
+ // required to ensure compatibility with MS implementation
+ public sealed partial class RC2CryptoServiceProvider : RC2 {
+
+ public override int EffectiveKeySize {
+ get { return base.EffectiveKeySize; }
+ set {
+ if (value != KeySizeValue)
+ throw new CryptographicUnexpectedOperationException ("Effective key size must match key size for compatibility");
+ base.EffectiveKeySize = value;
+ }
+ }
+ }
+}
--- /dev/null
+// ICryptoTransform implementation on top of CommonCrypto and SymmetricTransform
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+
+using Mono.Security.Cryptography;
+
+namespace Crimson.CommonCrypto {
+
+ class CryptorTransform : SymmetricTransform {
+
+ IntPtr handle;
+ IntPtr handle_e;
+ bool encryption;
+
+ public CryptorTransform (IntPtr cryptor, IntPtr special, SymmetricAlgorithm algo, bool encryption, byte[] iv)
+ : base (algo, encryption, iv)
+ {
+ handle = cryptor;
+ // for CFB we need to encrypt data while decrypting
+ handle_e = special;
+ this.encryption = encryption;
+ }
+
+ ~CryptorTransform ()
+ {
+ Dispose (false);
+ }
+
+ // PRO: doing this ensure all cipher modes and padding modes supported by .NET will be available with CommonCrypto (drop-in replacements)
+ // CON: doing this will only process one block at the time, so it's not ideal for performance, but still a lot better than managed
+ protected override void ECB (byte[] input, byte[] output)
+ {
+ IntPtr len = IntPtr.Zero;
+ CCCryptorStatus s = Cryptor.CCCryptorUpdate ((encrypt == encryption) ? handle : handle_e,
+ input, (IntPtr) input.Length, output, (IntPtr) output.Length, ref len);
+ if (((int) len != output.Length) || (s != CCCryptorStatus.Success))
+ throw new CryptographicUnexpectedOperationException (s.ToString ());
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (handle != IntPtr.Zero) {
+ Cryptor.CCCryptorRelease (handle);
+ handle = IntPtr.Zero;
+ }
+ if (handle_e != IntPtr.Zero) {
+ Cryptor.CCCryptorRelease (handle_e);
+ handle_e = IntPtr.Zero;
+ }
+ base.Dispose (disposing);
+ GC.SuppressFinalize (this);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Fast, multi-block, ICryptoTransform implementation on top of CommonCrypto
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+
+using Mono.Security.Cryptography;
+
+namespace Crimson.CommonCrypto {
+
+ unsafe class FastCryptorTransform : ICryptoTransform {
+
+ IntPtr handle;
+ bool encrypt;
+ int BlockSizeByte;
+ byte[] workBuff;
+ bool lastBlock;
+ PaddingMode padding;
+
+ public FastCryptorTransform (IntPtr cryptor, SymmetricAlgorithm algo, bool encryption, byte[] iv)
+ {
+ BlockSizeByte = (algo.BlockSize >> 3);
+
+ if (iv == null) {
+ iv = KeyBuilder.IV (BlockSizeByte);
+ } else if (iv.Length < BlockSizeByte) {
+ string msg = String.Format ("IV is too small ({0} bytes), it should be {1} bytes long.",
+ iv.Length, BlockSizeByte);
+ throw new CryptographicException (msg);
+ }
+
+ handle = cryptor;
+ encrypt = encryption;
+ padding = algo.Padding;
+ // transform buffer
+ workBuff = new byte [BlockSizeByte];
+ }
+
+ ~FastCryptorTransform ()
+ {
+ Dispose (false);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (handle != IntPtr.Zero) {
+ Cryptor.CCCryptorRelease (handle);
+ handle = IntPtr.Zero;
+ }
+ GC.SuppressFinalize (this);
+ }
+
+ public virtual bool CanTransformMultipleBlocks {
+ get { return true; }
+ }
+
+ public virtual bool CanReuseTransform {
+ get { return false; }
+ }
+
+ public virtual int InputBlockSize {
+ get { return BlockSizeByte; }
+ }
+
+ public virtual int OutputBlockSize {
+ get { return BlockSizeByte; }
+ }
+
+ int Transform (byte[] input, int inputOffset, byte[] output, int outputOffset, int length)
+ {
+ IntPtr len = IntPtr.Zero;
+ IntPtr in_len = (IntPtr) length;
+ IntPtr out_len = (IntPtr) (output.Length - outputOffset);
+ fixed (byte* inputBuffer = &input [0])
+ fixed (byte* outputBuffer = &output [0]) {
+ CCCryptorStatus s = Cryptor.CCCryptorUpdate (handle, (IntPtr) (inputBuffer + inputOffset), in_len, (IntPtr) (outputBuffer + outputOffset), out_len, ref len);
+ if (s != CCCryptorStatus.Success)
+ throw new CryptographicException (s.ToString ());
+ }
+ return (int) len;
+ }
+
+ private void CheckInput (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (inputBuffer == null)
+ throw new ArgumentNullException ("inputBuffer");
+ if (inputOffset < 0)
+ throw new ArgumentOutOfRangeException ("inputOffset", "< 0");
+ if (inputCount < 0)
+ throw new ArgumentOutOfRangeException ("inputCount", "< 0");
+ // ordered to avoid possible integer overflow
+ if (inputOffset > inputBuffer.Length - inputCount)
+ throw new ArgumentException ("inputBuffer", "Overflow");
+ }
+
+ // this method may get called MANY times so this is the one to optimize
+ public virtual int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ CheckInput (inputBuffer, inputOffset, inputCount);
+ // check output parameters
+ if (outputBuffer == null)
+ throw new ArgumentNullException ("outputBuffer");
+ if (outputOffset < 0)
+ throw new ArgumentOutOfRangeException ("outputOffset", "< 0");
+
+ // ordered to avoid possible integer overflow
+ int len = outputBuffer.Length - inputCount - outputOffset;
+ if (!encrypt && (0 > len) && ((padding == PaddingMode.None) || (padding == PaddingMode.Zeros))) {
+ throw new CryptographicException ("outputBuffer", "Overflow");
+ } else if (KeepLastBlock) {
+ if (0 > len + BlockSizeByte) {
+ throw new CryptographicException ("outputBuffer", "Overflow");
+ }
+ } else {
+ if (0 > len) {
+ // there's a special case if this is the end of the decryption process
+ if (inputBuffer.Length - inputOffset - outputBuffer.Length == BlockSizeByte)
+ inputCount = outputBuffer.Length - outputOffset;
+ else
+ throw new CryptographicException ("outputBuffer", "Overflow");
+ }
+ }
+ return InternalTransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
+ }
+
+ private bool KeepLastBlock {
+ get {
+ return ((!encrypt) && (padding != PaddingMode.None) && (padding != PaddingMode.Zeros));
+ }
+ }
+
+ private int InternalTransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ int offs = inputOffset;
+ int full;
+
+ // this way we don't do a modulo every time we're called
+ // and we may save a division
+ if (inputCount != BlockSizeByte) {
+ if ((inputCount % BlockSizeByte) != 0)
+ throw new CryptographicException ("Invalid input block size.");
+
+ full = inputCount / BlockSizeByte;
+ } else
+ full = 1;
+
+ if (KeepLastBlock)
+ full--;
+
+ int total = 0;
+
+ if (lastBlock) {
+ Transform (workBuff, 0, outputBuffer, outputOffset, BlockSizeByte);
+ outputOffset += BlockSizeByte;
+ total += BlockSizeByte;
+ lastBlock = false;
+ }
+
+ if (full > 0) {
+ int length = full * BlockSizeByte;
+ Transform (inputBuffer, offs, outputBuffer, outputOffset, length);
+ offs += length;
+ outputOffset += length;
+ total += length;
+ }
+
+ if (KeepLastBlock) {
+ Buffer.BlockCopy (inputBuffer, offs, workBuff, 0, BlockSizeByte);
+ lastBlock = true;
+ }
+
+ return total;
+ }
+
+ private void Random (byte[] buffer, int start, int length)
+ {
+ byte[] random = new byte [length];
+ Cryptor.GetRandom (random);
+ Buffer.BlockCopy (random, 0, buffer, start, length);
+ }
+
+ private void ThrowBadPaddingException (PaddingMode padding, int length, int position)
+ {
+ string msg = String.Format ("Bad {0} padding.", padding);
+ if (length >= 0)
+ msg += String.Format (" Invalid length {0}.", length);
+ if (position >= 0)
+ msg += String.Format (" Error found at position {0}.", position);
+ throw new CryptographicException (msg);
+ }
+
+ private byte[] FinalEncrypt (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ // are there still full block to process ?
+ int full = (inputCount / BlockSizeByte) * BlockSizeByte;
+ int rem = inputCount - full;
+ int total = full;
+
+ switch (padding) {
+ case PaddingMode.ANSIX923:
+ case PaddingMode.ISO10126:
+ case PaddingMode.PKCS7:
+ // we need to add an extra block for padding
+ total += BlockSizeByte;
+ break;
+ default:
+ if (inputCount == 0)
+ return new byte [0];
+ if (rem != 0) {
+ if (padding == PaddingMode.None)
+ throw new CryptographicException ("invalid block length");
+ // zero padding the input (by adding a block for the partial data)
+ byte[] paddedInput = new byte [full + BlockSizeByte];
+ Buffer.BlockCopy (inputBuffer, inputOffset, paddedInput, 0, inputCount);
+ inputBuffer = paddedInput;
+ inputOffset = 0;
+ inputCount = paddedInput.Length;
+ total = inputCount;
+ }
+ break;
+ }
+
+ byte[] res = new byte [total];
+ int outputOffset = 0;
+
+ // process all blocks except the last (final) block
+ if (total > BlockSizeByte) {
+ outputOffset = InternalTransformBlock (inputBuffer, inputOffset, total - BlockSizeByte, res, 0);
+ inputOffset += outputOffset;
+ }
+
+ // now we only have a single last block to encrypt
+ byte pad = (byte) (BlockSizeByte - rem);
+ switch (padding) {
+ case PaddingMode.ANSIX923:
+ // XX 00 00 00 00 00 00 07 (zero + padding length)
+ res [res.Length - 1] = pad;
+ Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem);
+ // the last padded block will be transformed in-place
+ InternalTransformBlock (res, full, BlockSizeByte, res, full);
+ break;
+ case PaddingMode.ISO10126:
+ // XX 3F 52 2A 81 AB F7 07 (random + padding length)
+ Random (res, res.Length - pad, pad - 1);
+ res [res.Length - 1] = pad;
+ Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem);
+ // the last padded block will be transformed in-place
+ InternalTransformBlock (res, full, BlockSizeByte, res, full);
+ break;
+ case PaddingMode.PKCS7:
+ // XX 07 07 07 07 07 07 07 (padding length)
+ for (int i = res.Length; --i >= (res.Length - pad);)
+ res [i] = pad;
+ Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem);
+ // the last padded block will be transformed in-place
+ InternalTransformBlock (res, full, BlockSizeByte, res, full);
+ break;
+ default:
+ InternalTransformBlock (inputBuffer, inputOffset, BlockSizeByte, res, outputOffset);
+ break;
+ }
+ return res;
+ }
+
+ private byte[] FinalDecrypt (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if ((inputCount % BlockSizeByte) > 0)
+ throw new CryptographicException ("Invalid input block size.");
+
+ int total = inputCount;
+ if (lastBlock)
+ total += BlockSizeByte;
+
+ byte[] res = new byte [total];
+ int outputOffset = 0;
+
+ if (inputCount > 0)
+ outputOffset = InternalTransformBlock (inputBuffer, inputOffset, inputCount, res, 0);
+
+ if (lastBlock) {
+ Transform (workBuff, 0, res, outputOffset, BlockSizeByte);
+ outputOffset += BlockSizeByte;
+ lastBlock = false;
+ }
+
+ // total may be 0 (e.g. PaddingMode.None)
+ byte pad = ((total > 0) ? res [total - 1] : (byte) 0);
+ switch (padding) {
+ case PaddingMode.ANSIX923:
+ if ((pad == 0) || (pad > BlockSizeByte))
+ ThrowBadPaddingException (padding, pad, -1);
+ for (int i = pad - 1; i > 0; i--) {
+ if (res [total - 1 - i] != 0x00)
+ ThrowBadPaddingException (padding, -1, i);
+ }
+ total -= pad;
+ break;
+ case PaddingMode.ISO10126:
+ if ((pad == 0) || (pad > BlockSizeByte))
+ ThrowBadPaddingException (padding, pad, -1);
+ total -= pad;
+ break;
+ case PaddingMode.PKCS7:
+ if ((pad == 0) || (pad > BlockSizeByte))
+ ThrowBadPaddingException (padding, pad, -1);
+ for (int i = pad - 1; i > 0; i--) {
+ if (res [total - 1 - i] != pad)
+ ThrowBadPaddingException (padding, -1, i);
+ }
+ total -= pad;
+ break;
+ case PaddingMode.None: // nothing to do - it's a multiple of block size
+ case PaddingMode.Zeros: // nothing to do - user must unpad himself
+ break;
+ }
+
+ // return output without padding
+ if (total > 0) {
+ byte[] data = new byte [total];
+ Buffer.BlockCopy (res, 0, data, 0, total);
+ // zeroize decrypted data (copy with padding)
+ Array.Clear (res, 0, res.Length);
+ return data;
+ }
+ else
+ return new byte [0];
+ }
+
+ public virtual byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ CheckInput (inputBuffer, inputOffset, inputCount);
+
+ if (encrypt)
+ return FinalEncrypt (inputBuffer, inputOffset, inputCount);
+ else
+ return FinalDecrypt (inputBuffer, inputOffset, inputCount);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+CommonCrypto/%.g.cs: CommonCrypto/generator.exe
+ cd CommonCrypto && mono --debug generator.exe
+
+CommonCrypto/generator.exe: CommonCrypto/generator.cs CommonCrypto/CommonDigestGenerator.cs CommonCrypto/CommonCryptorGenerator.cs
+ mcs CommonCrypto/generator.cs CommonCrypto/CommonDigestGenerator.cs CommonCrypto/CommonCryptorGenerator.cs -o $@
--- /dev/null
+// A CommonCrypto-based implementation of RC4(tm)
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright 2012-2014 Xamarin Inc.
+
+using System;
+using System.Security.Cryptography;
+
+using Crimson.CommonCrypto;
+
+#if MONOTOUCH || XAMMAC
+using Mono.Security.Cryptography;
+
+namespace Mono.Security.Cryptography {
+
+#if !INSIDE_CORLIB
+ public
+#endif
+ sealed partial class ARC4Managed : RC4, ICryptoTransform {
+
+ IntPtr handle;
+
+ public ARC4Managed ()
+ {
+ }
+
+ ~ARC4Managed ()
+ {
+ Dispose (false);
+ }
+#else
+namespace Crimson.Security.Cryptography {
+
+ public abstract class RC4 : SymmetricAlgorithm {
+
+ private static KeySizes[] s_legalBlockSizes = {
+ new KeySizes (64, 64, 0)
+ };
+
+ private static KeySizes[] s_legalKeySizes = {
+ new KeySizes (40, 512, 8)
+ };
+
+ public RC4 ()
+ {
+ KeySizeValue = 128;
+ BlockSizeValue = 64;
+ FeedbackSizeValue = BlockSizeValue;
+ LegalBlockSizesValue = s_legalBlockSizes;
+ LegalKeySizesValue = s_legalKeySizes;
+ }
+
+ // required for compatibility with .NET 2.0
+ public override byte[] IV {
+ get { return new byte [0]; }
+ set { ; }
+ }
+
+ new static public RC4 Create()
+ {
+ return Create ("RC4");
+ }
+
+ new static public RC4 Create (string algName)
+ {
+ object o = CryptoConfig.CreateFromName (algName);
+ return (RC4) o ?? new RC4CommonCrypto ();
+ }
+ }
+
+ public sealed class RC4CommonCrypto : RC4, ICryptoTransform {
+
+ IntPtr handle;
+
+ public RC4CommonCrypto ()
+ {
+ }
+
+ ~RC4CommonCrypto ()
+ {
+ Dispose (false);
+ }
+#endif
+
+ public bool CanReuseTransform {
+ get { return false; }
+ }
+
+ public bool CanTransformMultipleBlocks {
+ get { return true; }
+ }
+
+ public int InputBlockSize {
+ get { return 1; }
+ }
+
+ public int OutputBlockSize {
+ get { return 1; }
+ }
+
+ public override byte[] Key {
+ get {
+ return base.Key;
+ }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("Key");
+
+ int length = (value.Length << 3);
+ KeySizeValue = length;
+ KeyValue = (byte[]) value.Clone ();
+ }
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (handle != IntPtr.Zero) {
+ Cryptor.CCCryptorRelease (handle);
+ handle = IntPtr.Zero;
+ }
+ base.Dispose (disposing);
+ GC.SuppressFinalize (this);
+ }
+
+ public override void GenerateIV ()
+ {
+ // not used for a stream cipher
+ IVValue = new byte [0];
+ }
+
+ public override void GenerateKey ()
+ {
+ KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+ }
+
+ public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ KeyValue = rgbKey;
+ IVValue = rgbIV;
+ return this;
+ }
+
+ public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ KeyValue = rgbKey;
+ IVValue = rgbIV;
+ return this;
+ }
+
+ private void CheckInput (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (inputBuffer == null)
+ throw new ArgumentNullException ("inputBuffer");
+ if (inputOffset < 0)
+ throw new ArgumentOutOfRangeException ("inputOffset", "< 0");
+ if (inputCount < 0)
+ throw new ArgumentOutOfRangeException ("inputCount", "< 0");
+ // ordered to avoid possible integer overflow
+ if (inputOffset > inputBuffer.Length - inputCount)
+ throw new ArgumentException ("inputBuffer", "Overflow");
+ }
+
+ public unsafe int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ CheckInput (inputBuffer, inputOffset, inputCount);
+ if (inputCount == 0)
+ return 0;
+
+ // check output parameters
+ if (outputBuffer == null)
+ throw new ArgumentNullException ("outputBuffer");
+ if (outputOffset < 0)
+ throw new ArgumentOutOfRangeException ("outputOffset", "< 0");
+ // ordered to avoid possible integer overflow
+ if (outputOffset > outputBuffer.Length - inputCount)
+ throw new ArgumentException ("outputBuffer", "Overflow");
+ if (outputBuffer.Length == 0)
+ throw new CryptographicException ("output buffer too small");
+
+ if (handle == IntPtr.Zero)
+ handle = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.RC4, CCOptions.None, KeyValue, IVValue);
+
+ IntPtr len = IntPtr.Zero;
+ IntPtr in_len = (IntPtr) (inputBuffer.Length - inputOffset);
+ IntPtr out_len = (IntPtr) (outputBuffer.Length - outputOffset);
+ fixed (byte* input = &inputBuffer [0])
+ fixed (byte* output = &outputBuffer [0]) {
+ CCCryptorStatus s = Cryptor.CCCryptorUpdate (handle, (IntPtr) (input + inputOffset), in_len, (IntPtr) (output + outputOffset), out_len, ref len);
+ if ((len != out_len) || (s != CCCryptorStatus.Success))
+ throw new CryptographicUnexpectedOperationException (s.ToString ());
+ }
+ return (int) out_len;
+ }
+
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ CheckInput (inputBuffer, inputOffset, inputCount);
+ try {
+ byte[] output = new byte [inputCount];
+ TransformBlock (inputBuffer, inputOffset, inputCount, output, 0);
+ return output;
+ }
+ finally {
+ Cryptor.CCCryptorRelease (handle);
+ handle = IntPtr.Zero;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// RijndaelManaged.cs: Use CommonCrypto AES when possible,
+// fallback on RijndaelManagedTransform otherwise
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012 Xamarin Inc.
+//
+
+using System;
+using System.Security.Cryptography;
+
+using Mono.Security.Cryptography;
+using Crimson.CommonCrypto;
+
+namespace System.Security.Cryptography {
+
+ public sealed class RijndaelManaged : Rijndael {
+
+ public RijndaelManaged ()
+ {
+ }
+
+ public override void GenerateIV ()
+ {
+ IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
+ }
+
+ public override void GenerateKey ()
+ {
+ KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+ }
+
+ public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ // AES is Rijndael with a 128 bits block size, so we can use CommonCrypto in this case
+ if (BlockSize == 128) {
+ IntPtr decryptor = IntPtr.Zero;
+ switch (Mode) {
+ case CipherMode.CBC:
+ decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV);
+ return new FastCryptorTransform (decryptor, this, false, rgbIV);
+ case CipherMode.ECB:
+ decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new FastCryptorTransform (decryptor, this, false, rgbIV);
+ default:
+ // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them
+ // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode
+ break;
+ }
+ }
+
+ return NewEncryptor(rgbKey,
+ ModeValue,
+ rgbIV,
+ FeedbackSizeValue,
+ RijndaelManagedTransformMode.Decrypt);
+ }
+
+ public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
+ {
+ if (BlockSize == 128) {
+ IntPtr encryptor = IntPtr.Zero;
+ switch (Mode) {
+ case CipherMode.CBC:
+ encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV);
+ return new FastCryptorTransform (encryptor, this, true, rgbIV);
+ case CipherMode.ECB:
+ encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV);
+ return new FastCryptorTransform (encryptor, this, true, rgbIV);
+ default:
+ // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them
+ // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode
+ break;
+ }
+ }
+
+ return NewEncryptor(rgbKey,
+ ModeValue,
+ rgbIV,
+ FeedbackSizeValue,
+ RijndaelManagedTransformMode.Encrypt);
+ }
+
+
+ private ICryptoTransform NewEncryptor (byte[] rgbKey,
+ CipherMode mode,
+ byte[] rgbIV,
+ int feedbackSize,
+ RijndaelManagedTransformMode encryptMode) {
+ // Build the key if one does not already exist
+ if (rgbKey == null) {
+ rgbKey = Utils.GenerateRandom(KeySizeValue / 8);
+ }
+
+ // If not ECB mode, make sure we have an IV. In CoreCLR we do not support ECB, so we must have
+ // an IV in all cases.
+#if !FEATURE_CRYPTO
+ if (mode != CipherMode.ECB) {
+#endif // !FEATURE_CRYPTO
+ if (rgbIV == null) {
+ rgbIV = Utils.GenerateRandom(BlockSizeValue / 8);
+ }
+#if !FEATURE_CRYPTO
+ }
+#endif // !FEATURE_CRYPTO
+
+ // Create the encryptor/decryptor object
+ return new RijndaelManagedTransform (rgbKey,
+ mode,
+ rgbIV,
+ BlockSizeValue,
+ feedbackSize,
+ PaddingValue,
+ encryptMode);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SecRandom.cs: based on Mono's System.Security.Cryptography.RNGCryptoServiceProvider
+//
+// Authors:
+// Mark Crichton (crichton@gimp.org)
+// Sebastien Pouliot (sebastien@xamarun.com)
+//
+// (C) 2002
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2012-2014 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Crimson.CommonCrypto;
+
+// http://developer.apple.com/library/ios/#DOCUMENTATION/Security/Reference/RandomizationReference/Reference/reference.html
+#if MONOTOUCH || XAMMAC
+namespace System.Security.Cryptography {
+ public class RNGCryptoServiceProvider : RandomNumberGenerator {
+ public RNGCryptoServiceProvider ()
+ {
+ }
+
+ ~RNGCryptoServiceProvider ()
+ {
+ }
+#else
+using System;
+using System.Security.Cryptography;
+
+namespace Crimson.Security.Cryptography {
+
+ public class SecRandom : RandomNumberGenerator {
+#endif
+
+ public override void GetBytes (byte[] data)
+ {
+ if (data == null)
+ throw new ArgumentNullException ("data");
+
+ Cryptor.GetRandom (data);
+ }
+
+ public override void GetNonZeroBytes (byte[] data)
+ {
+ if (data == null)
+ throw new ArgumentNullException ("data");
+
+ byte[] random = new byte [data.Length * 2];
+ int i = 0;
+ // one pass should be enough but hey this is random ;-)
+ while (i < data.Length) {
+ Cryptor.GetRandom (random);
+ for (int j=0; j < random.Length; j++) {
+ if (i == data.Length)
+ break;
+ if (random [j] != 0)
+ data [i++] = random [j];
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// CommonCrypto Code Generator
+//
+// Authors:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// Copyright 2012 Xamarin Inc.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Xamarin {
+
+ class Program {
+ static void Main (string [] args)
+ {
+ // mscorlib replacements
+ CommonDigest.Generate ("System.Security.Cryptography", "MD5CryptoServiceProvider", "MD5", 1000);
+ CommonDigest.Generate ("System.Security.Cryptography", "SHA1CryptoServiceProvider", "SHA1", 1000);
+ CommonDigest.Generate ("System.Security.Cryptography", "SHA1Managed", "SHA1", 1000);
+ CommonDigest.Generate ("System.Security.Cryptography", "SHA256Managed", "SHA256", 1000);
+ CommonDigest.Generate ("System.Security.Cryptography", "SHA384Managed", "SHA384", 1000);
+ CommonDigest.Generate ("System.Security.Cryptography", "SHA512Managed", "SHA512", 1000);
+
+ // System.Core replacements - not yet in MT profile (4.0 - functional dupes anyway)
+ //CommonDigest.Generate ("System.Security.Cryptography", "MD5Cng", "MD5", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA256Cng", "SHA256", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA384Cng", "SHA384", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA512Cng", "SHA512", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA256CryptoServiceProvider", "SHA256", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA384CryptoServiceProvider", "SHA384", 1000);
+ //CommonDigest.Generate ("System.Security.Cryptography", "SHA512CryptoServiceProvider", "SHA512", 1000);
+
+ // Mono.Security replacements
+ CommonDigest.Generate ("Mono.Security.Cryptography", "MD2Managed", "MD2", 1000, "#if !INSIDE_CORLIB", "#endif");
+ CommonDigest.Generate ("Mono.Security.Cryptography", "MD4Managed", "MD4", 1000, "#if !INSIDE_CORLIB", "#endif");
+ CommonDigest.Generate ("Mono.Security.Cryptography", "SHA224Managed", "SHA224", 1000);
+
+ // mscorlib replacements
+ CommonCryptor.Generate ("System.Security.Cryptography", "DESCryptoServiceProvider", "DES", "DES");
+ CommonCryptor.Generate ("System.Security.Cryptography", "TripleDESCryptoServiceProvider", "TripleDES", "TripleDES");
+ CommonCryptor.Generate ("System.Security.Cryptography", "RC2CryptoServiceProvider", "RC2", "RC2", ctorInitializers: "LegalKeySizesValue = new[] { new KeySizes(40, 128, 8) };");
+ // Rijndael supports block sizes that are not available in AES - as such it does not use the same generated code
+ // but has it's own version, using AES (128 bits block size) and falling back to managed (192/256 bits block size)
+
+ // System.Core replacements
+ CommonCryptor.Generate ("System.Security.Cryptography", "AesManaged", "Aes", "AES128", "128");
+ CommonCryptor.Generate ("System.Security.Cryptography", "AesCryptoServiceProvider", "Aes", "AES128");
+
+ // Mono.Security replacements
+ // RC4 is a stream (not a block) cipher so it can not reuse the generated code
+ }
+ }
+}
\ No newline at end of file
thisdir = class/corlib
SUBDIRS =
include ../../build/rules.make
+include CommonCrypto/Makefile.include
export __SECURITY_BOOTSTRAP_DB=$(topdir)/class/corlib
LIBRARY = corlib.dll
--- /dev/null
+System.Security.Cryptography/MD5CryptoServiceProvider.cs
+System.Security.Cryptography/SHA1CryptoServiceProvider.cs
+System.Security.Cryptography/SHA1CryptoServiceProvider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha1managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha256managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha384managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha512managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs
+System.Security.Cryptography/RNGCryptoServiceProvider.cs
+../Mono.Security/Mono.Security.Cryptography/ARC4Managed.cs
+../Mono.Security/Mono.Security.Cryptography/MD2Managed.cs
+../Mono.Security/Mono.Security.Cryptography/MD4Managed.cs
#include corlib.dll.sources
+CommonCrypto/CommonCrypto.cs
+CommonCrypto/CryptorTransform.cs
+CommonCrypto/FastCryptorTransform.cs
+CommonCrypto/CorlibExtras.cs
+CommonCrypto/MD5CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1Managed.g.cs
+CommonCrypto/SHA256Managed.g.cs
+CommonCrypto/SHA384Managed.g.cs
+CommonCrypto/SHA512Managed.g.cs
+CommonCrypto/TripleDESCryptoServiceProvider.g.cs
+CommonCrypto/DESCryptoServiceProvider.g.cs
+CommonCrypto/RC2CryptoServiceProvider.g.cs
+CommonCrypto/RijndaelManaged.cs
+CommonCrypto/SecRandom.cs
+CommonCrypto/RC4CommonCrypto.cs
+CommonCrypto/MD2Managed.g.cs
+CommonCrypto/MD4Managed.g.cs
--- /dev/null
+#include monotouch_corlib.dll.exclude.sources
#include corlib.dll.sources
+CommonCrypto/CommonCrypto.cs
+CommonCrypto/CryptorTransform.cs
+CommonCrypto/FastCryptorTransform.cs
+CommonCrypto/CorlibExtras.cs
+CommonCrypto/MD5CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1Managed.g.cs
+CommonCrypto/SHA256Managed.g.cs
+CommonCrypto/SHA384Managed.g.cs
+CommonCrypto/SHA512Managed.g.cs
+CommonCrypto/TripleDESCryptoServiceProvider.g.cs
+CommonCrypto/DESCryptoServiceProvider.g.cs
+CommonCrypto/RC2CryptoServiceProvider.g.cs
+CommonCrypto/RijndaelManaged.cs
+CommonCrypto/SecRandom.cs
+CommonCrypto/RC4CommonCrypto.cs
+CommonCrypto/MD2Managed.g.cs
+CommonCrypto/MD4Managed.g.cs
--- /dev/null
+#include monotouch_corlib.dll.exclude.sources
#include corlib.dll.sources
+CommonCrypto/CommonCrypto.cs
+CommonCrypto/CryptorTransform.cs
+CommonCrypto/FastCryptorTransform.cs
+CommonCrypto/CorlibExtras.cs
+CommonCrypto/MD5CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1Managed.g.cs
+CommonCrypto/SHA256Managed.g.cs
+CommonCrypto/SHA384Managed.g.cs
+CommonCrypto/SHA512Managed.g.cs
+CommonCrypto/TripleDESCryptoServiceProvider.g.cs
+CommonCrypto/DESCryptoServiceProvider.g.cs
+CommonCrypto/RC2CryptoServiceProvider.g.cs
+CommonCrypto/RijndaelManaged.cs
+CommonCrypto/SecRandom.cs
+CommonCrypto/RC4CommonCrypto.cs
+CommonCrypto/MD2Managed.g.cs
+CommonCrypto/MD4Managed.g.cs
--- /dev/null
+#include monotouch_corlib.dll.exclude.sources
--- /dev/null
+#include monotouch_corlib.dll.exclude.sources
#include corlib.dll.sources
+CommonCrypto/CommonCrypto.cs
+CommonCrypto/CryptorTransform.cs
+CommonCrypto/FastCryptorTransform.cs
+CommonCrypto/CorlibExtras.cs
+CommonCrypto/MD5CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1Managed.g.cs
+CommonCrypto/SHA256Managed.g.cs
+CommonCrypto/SHA384Managed.g.cs
+CommonCrypto/SHA512Managed.g.cs
+CommonCrypto/TripleDESCryptoServiceProvider.g.cs
+CommonCrypto/DESCryptoServiceProvider.g.cs
+CommonCrypto/RC2CryptoServiceProvider.g.cs
+CommonCrypto/RijndaelManaged.cs
+CommonCrypto/SecRandom.cs
+CommonCrypto/RC4CommonCrypto.cs
+CommonCrypto/MD2Managed.g.cs
+CommonCrypto/MD4Managed.g.cs
--- /dev/null
+#include monotouch_corlib.dll.exclude.sources
--- /dev/null
+System.Security.Cryptography/MD5CryptoServiceProvider.cs
+System.Security.Cryptography/SHA1CryptoServiceProvider.cs
+System.Security.Cryptography/SHA1CryptoServiceProvider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha1managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha256managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha384managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/sha512managed.cs
+../../../external/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs
+../Mono.Security/Mono.Security.Cryptography/ARC4Managed.cs
+../Mono.Security/Mono.Security.Cryptography/MD2Managed.cs
+../Mono.Security/Mono.Security.Cryptography/MD4Managed.cs
#include corlib.dll.sources
+CommonCrypto/CommonCrypto.cs
+CommonCrypto/CryptorTransform.cs
+CommonCrypto/FastCryptorTransform.cs
+CommonCrypto/CorlibExtras.cs
+CommonCrypto/MD5CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1CryptoServiceProvider.g.cs
+CommonCrypto/SHA1Managed.g.cs
+CommonCrypto/SHA256Managed.g.cs
+CommonCrypto/SHA384Managed.g.cs
+CommonCrypto/SHA512Managed.g.cs
+CommonCrypto/TripleDESCryptoServiceProvider.g.cs
+CommonCrypto/DESCryptoServiceProvider.g.cs
+CommonCrypto/RC2CryptoServiceProvider.g.cs
+CommonCrypto/RijndaelManaged.cs
+CommonCrypto/RC4CommonCrypto.cs
+CommonCrypto/MD2Managed.g.cs
+CommonCrypto/MD4Managed.g.cs