2 // RijndaelManaged.cs: Use CommonCrypto AES when possible,
3 // fallback on RijndaelManagedTransform otherwise
6 // Sebastien Pouliot <sebastien@xamarin.com>
8 // Copyright 2012 Xamarin Inc.
12 using System.Security.Cryptography;
14 using Mono.Security.Cryptography;
15 using Crimson.CommonCrypto;
17 namespace System.Security.Cryptography {
19 public sealed class RijndaelManaged : Rijndael {
21 public RijndaelManaged ()
25 public override void GenerateIV ()
27 IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
30 public override void GenerateKey ()
32 KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
35 public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
37 // AES is Rijndael with a 128 bits block size, so we can use CommonCrypto in this case
38 if (BlockSize == 128) {
39 IntPtr decryptor = IntPtr.Zero;
42 decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV);
43 return new FastCryptorTransform (decryptor, this, false, rgbIV);
45 decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV);
46 return new FastCryptorTransform (decryptor, this, false, rgbIV);
48 // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them
49 // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode
54 return NewEncryptor(rgbKey,
58 RijndaelManagedTransformMode.Decrypt);
61 public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
63 if (BlockSize == 128) {
64 IntPtr encryptor = IntPtr.Zero;
67 encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV);
68 return new FastCryptorTransform (encryptor, this, true, rgbIV);
70 encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV);
71 return new FastCryptorTransform (encryptor, this, true, rgbIV);
73 // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them
74 // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode
79 return NewEncryptor(rgbKey,
83 RijndaelManagedTransformMode.Encrypt);
87 private ICryptoTransform NewEncryptor (byte[] rgbKey,
91 RijndaelManagedTransformMode encryptMode) {
92 // Build the key if one does not already exist
94 rgbKey = Utils.GenerateRandom(KeySizeValue / 8);
97 // If not ECB mode, make sure we have an IV. In CoreCLR we do not support ECB, so we must have
98 // an IV in all cases.
100 if (mode != CipherMode.ECB) {
101 #endif // !FEATURE_CRYPTO
103 rgbIV = Utils.GenerateRandom(BlockSizeValue / 8);
107 #endif // !FEATURE_CRYPTO
109 // Create the encryptor/decryptor object
110 return new RijndaelManagedTransform (rgbKey,