56d89ed2ee435436d66c0c689310049705c1e6b7
[mono.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / des.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 // 
8
9 //
10 // DES.cs
11 //
12
13 namespace System.Security.Cryptography {
14     using System;
15     using System.Diagnostics.Contracts;
16
17 [System.Runtime.InteropServices.ComVisible(true)]
18     public abstract class DES : SymmetricAlgorithm
19     {
20         private static  KeySizes[] s_legalBlockSizes = {
21             new KeySizes(64, 64, 0)
22         };
23         private static  KeySizes[] s_legalKeySizes = {
24             new KeySizes(64, 64, 0)
25         };
26       
27         //
28         // protected constructors
29         //
30     
31         protected DES() {
32             KeySizeValue = 64;
33             BlockSizeValue = 64;
34             FeedbackSizeValue = BlockSizeValue;
35             LegalBlockSizesValue = s_legalBlockSizes;
36             LegalKeySizesValue = s_legalKeySizes;
37         }
38     
39         //
40         // public properties
41         //
42
43         public override byte[] Key {
44             get { 
45                 if (KeyValue == null) {
46                     // Never hand back a weak or semi-weak key
47                     do {
48                         GenerateKey();
49                     } while (IsWeakKey(KeyValue) || IsSemiWeakKey(KeyValue));
50                 }
51                 return (byte[]) KeyValue.Clone();
52             }
53             set {
54                 if (value == null) throw new ArgumentNullException("value");
55                 Contract.EndContractBlock();
56                 if (!ValidKeySize(value.Length * 8)) { // must convert bytes to bits
57                     throw new ArgumentException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
58                 }
59                 if (IsWeakKey(value)) {
60                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"DES");
61                 }
62                 if (IsSemiWeakKey(value)) {
63                     throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_SemiWeak"),"DES");
64                 }
65                 KeyValue = (byte[]) value.Clone();
66                 KeySizeValue = value.Length * 8;
67             }
68         }
69
70         //
71         // public methods
72         //
73
74         new static public DES Create() {
75 #if FULL_AOT_RUNTIME
76         return new System.Security.Cryptography.DESCryptoServiceProvider ();
77 #else
78             return Create("System.Security.Cryptography.DES");
79 #endif
80         }
81
82         new static public DES Create(String algName) {
83             return (DES) CryptoConfig.CreateFromName(algName);
84         }
85
86         public static bool IsWeakKey(byte[] rgbKey) {
87             if (!IsLegalKeySize(rgbKey)) {
88                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
89             }
90             byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
91             UInt64 key = QuadWordFromBigEndian(rgbOddParityKey);
92             if ((key == 0x0101010101010101) ||
93                 (key == 0xfefefefefefefefe) ||
94                 (key == 0x1f1f1f1f0e0e0e0e) ||
95                 (key == 0xe0e0e0e0f1f1f1f1)) {
96                 return(true);
97             }
98             return(false);
99         }
100
101         public static bool IsSemiWeakKey(byte[] rgbKey) {
102             if (!IsLegalKeySize(rgbKey)) {
103                 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
104             }
105             byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
106             UInt64 key = QuadWordFromBigEndian(rgbOddParityKey);
107             if ((key == 0x01fe01fe01fe01fe) ||
108                 (key == 0xfe01fe01fe01fe01) ||
109                 (key == 0x1fe01fe00ef10ef1) ||
110                 (key == 0xe01fe01ff10ef10e) ||
111                 (key == 0x01e001e001f101f1) ||
112                 (key == 0xe001e001f101f101) ||
113                 (key == 0x1ffe1ffe0efe0efe) ||
114                 (key == 0xfe1ffe1ffe0efe0e) ||
115                 (key == 0x011f011f010e010e) ||
116                 (key == 0x1f011f010e010e01) ||
117                 (key == 0xe0fee0fef1fef1fe) ||
118                 (key == 0xfee0fee0fef1fef1)) {
119                 return(true);
120             }
121             return(false);
122         }
123
124         //
125         // private methods
126         //
127
128         private static bool IsLegalKeySize(byte[] rgbKey) {
129             if (rgbKey != null && rgbKey.Length == 8) return(true);
130             return(false);
131         }
132             
133         private static UInt64 QuadWordFromBigEndian(byte[] block)
134         {
135             UInt64 x;
136             x =  (
137                   (((UInt64)block[0]) << 56) | (((UInt64)block[1]) << 48) |
138                   (((UInt64)block[2]) << 40) | (((UInt64)block[3]) << 32) |
139                   (((UInt64)block[4]) << 24) | (((UInt64)block[5]) << 16) |
140                   (((UInt64)block[6]) << 8) | ((UInt64)block[7])
141                   );
142             return(x);
143         }
144     }
145 }