Merge pull request #1505 from esdrubal/tzifloatingrule
[mono.git] / mcs / class / corlib / System.Security.Cryptography / TripleDESCryptoServiceProvider.cs
index 5c14c437d838a84a7350a447b8da206d32483dcd..ed8b1393304e889fb0351ce4c4bb134474f55146 100644 (file)
@@ -5,11 +5,7 @@
 //     Sebastien Pouliot <sebastien@ximian.com>
 //
 // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
-// (C) 2004 Novell (http://www.novell.com)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,7 +27,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
+using System.Runtime.InteropServices;
 using Mono.Security.Cryptography;
 
 namespace System.Security.Cryptography {
@@ -43,6 +39,7 @@ namespace System.Security.Cryptography {
        //      not free :-(
        //      http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
        
+       [ComVisible (true)]
        public sealed class TripleDESCryptoServiceProvider : TripleDES {
        
                public TripleDESCryptoServiceProvider ()
@@ -56,20 +53,16 @@ namespace System.Security.Cryptography {
                
                public override void GenerateKey () 
                {
-                       KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
+                       KeyValue = TripleDESTransform.GetStrongKey ();
                }
                
                public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) 
                {
-                       Key = rgbKey;
-                       IV = rgbIV;
                        return new TripleDESTransform (this, false, rgbKey, rgbIV);
                }
                
                public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) 
                {
-                       Key = rgbKey;
-                       IV = rgbIV;
                        return new TripleDESTransform (this, true, rgbKey, rgbIV);
                }
        }
@@ -89,6 +82,15 @@ namespace System.Security.Cryptography {
                
                public TripleDESTransform (TripleDES algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv) 
                {
+                       if (key == null) {
+                               key = GetStrongKey ();
+                       }
+                       // note: checking weak keys also checks valid key length
+                       if (TripleDES.IsWeakKey (key)) {
+                               string msg = Locale.GetText ("This is a known weak key.");
+                               throw new CryptographicException (msg);
+                       }
+
                        byte[] key1 = new byte [8];
                        byte[] key2 = new byte [8];
                        byte[] key3 = new byte [8];
@@ -117,19 +119,28 @@ namespace System.Security.Cryptography {
                // for both input and output
                protected override void ECB (byte[] input, byte[] output) 
                {
-                       byte[] temp = new byte [input.Length];
+                       DESTransform.Permutation (input, output, DESTransform.ipTab, false);
                        if (encrypt) {
-                               E1.ProcessBlock (input, output);
-                               D2.ProcessBlock (output, temp);
-                               E3.ProcessBlock (temp, output);
+                               E1.ProcessBlock (output, output);
+                               D2.ProcessBlock (output, output);
+                               E3.ProcessBlock (output, output);
                        }
                        else {
-                               D1.ProcessBlock (input, output);
-                               E2.ProcessBlock (output, temp);
-                               D3.ProcessBlock (temp, output);
-                               // don't keep decrypted content in memory
-                               Array.Clear (temp, 0, temp.Length);
+                               D1.ProcessBlock (output, output);
+                               E2.ProcessBlock (output, output);
+                               D3.ProcessBlock (output, output);
                        }
+                       DESTransform.Permutation (output, output, DESTransform.fpTab, true);
+               }
+
+               static internal byte[] GetStrongKey ()
+               {
+                       int size = DESTransform.BLOCK_BYTE_SIZE * 3;
+                       byte[] key = KeyBuilder.Key (size);
+                       while (TripleDES.IsWeakKey (key))
+                               key = KeyBuilder.Key (size);
+                       return key;
                }
        }
 }
+