Update Reference Sources to .NET Framework 4.6
[mono.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / tripledes.cs
1 using System.Diagnostics.Contracts;
2 // ==++==
3 // 
4 //   Copyright (c) Microsoft Corporation.  All rights reserved.
5 // 
6 // ==--==
7 // <OWNER>Microsoft</OWNER>
8 // 
9
10 //
11 // TripleDES.cs
12 //
13
14 namespace System.Security.Cryptography {
15 [System.Runtime.InteropServices.ComVisible(true)]
16     public abstract class TripleDES : SymmetricAlgorithm
17     {
18         private static  KeySizes[] s_legalBlockSizes = {
19             new KeySizes(64, 64, 0)
20         };
21
22         private static  KeySizes[] s_legalKeySizes = {
23             new KeySizes(2*64, 3*64, 64)
24         };
25       
26         //
27         // protected constructors
28         //
29     
30         protected TripleDES() {
31             KeySizeValue = 3*64;
32             BlockSizeValue = 64;
33             FeedbackSizeValue = BlockSizeValue;
34             LegalBlockSizesValue = s_legalBlockSizes;
35             LegalKeySizesValue = s_legalKeySizes;
36         }
37     
38         //
39         // public properties
40         //
41
42         public override byte[] Key {
43             get { 
44                 if (KeyValue == null) {
45                     // Never hand back a weak key
46                     do {
47                         GenerateKey();
48                     } while (IsWeakKey(KeyValue));
49                 }
50                 return (byte[]) KeyValue.Clone(); 
51             }
52             set {
53                 if (value == null) throw new ArgumentNullException("value");
54                 Contract.EndContractBlock();
55                 if (!ValidKeySize(value.Length * 8)) { // must convert bytes to bits
56                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
57                 }
58                 if (IsWeakKey(value)) {
59                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"TripleDES");
60                 }
61                 KeyValue = (byte[]) value.Clone();
62                 KeySizeValue = value.Length * 8;
63             }
64         }
65         
66         //
67         // public methods
68         //
69
70         new static public TripleDES Create() {
71 #if FULL_AOT_RUNTIME
72         return new System.Security.Cryptography.TripleDESCryptoServiceProvider ();
73 #else
74             return Create("System.Security.Cryptography.TripleDES");
75 #endif
76         }
77
78         new static public TripleDES Create(String str) {
79             return (TripleDES) CryptoConfig.CreateFromName(str);
80         }
81
82         public static bool IsWeakKey(byte[] rgbKey) {
83             // All we have to check for here is (a) we're in 3-key mode (192 bits), and
84             // (b) either K1 == K2 or K2 == K3
85             if (!IsLegalKeySize(rgbKey)) {
86                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
87             }
88             byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
89             if (EqualBytes(rgbOddParityKey,0,8,8)) return(true);
90             if ((rgbOddParityKey.Length == 24) && EqualBytes(rgbOddParityKey,8,16,8)) return(true);
91             return(false);
92         }
93     
94         //
95         // private methods
96         //
97
98         private static bool EqualBytes(byte[] rgbKey, int start1, int start2, int count) {
99             if (start1 < 0) throw new ArgumentOutOfRangeException("start1", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
100             if (start2 < 0) throw new ArgumentOutOfRangeException("start2", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
101             if ((start1+count) > rgbKey.Length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
102             if ((start2+count) > rgbKey.Length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
103             Contract.EndContractBlock();
104             for (int i = 0; i < count; i++) {
105                 if (rgbKey[start1+i] != rgbKey[start2+i]) return(false);
106             }
107             return(true);
108         }
109
110         private static bool IsLegalKeySize(byte[] rgbKey) {
111             if (rgbKey != null && ((rgbKey.Length == 16) || (rgbKey.Length == 24))) 
112                 return(true);
113             return(false);
114         }
115     }
116 }