lalala
[mono.git] / mcs / class / corlib / System.Security.Cryptography / DES.cs
1 //
2 // System.Security.Cryptography.DES
3 //
4 // Author:
5 //      Sergey Chaban (serge@wildwestsoftware.com)
6 //      Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 // (C) 2004 Novell (http://www.novell.com)
10 //
11
12 using System;
13 using System.Security.Cryptography;
14
15 // References:
16 // a.   FIPS PUB 46-3: Data Encryption Standard
17 //      http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
18
19 namespace System.Security.Cryptography {
20
21 public abstract class DES : SymmetricAlgorithm {
22
23         private static int blockSizeByte = 8;
24
25         public DES ()
26         {
27                 KeySizeValue = 64; 
28                 BlockSizeValue = 64; 
29                 FeedbackSizeValue = 64;
30
31                 LegalKeySizesValue = new KeySizes[1];
32                 LegalKeySizesValue[0] = new KeySizes(64, 64, 0);
33
34                 LegalBlockSizesValue = new KeySizes[1];
35                 LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);
36         }
37
38         public static new DES Create () 
39         {
40                 return Create ("System.Security.Cryptography.DES");
41         }
42
43         public static new DES Create (string algo) 
44         {
45                 return (DES) CryptoConfig.CreateFromName (algo);
46         }
47
48         internal static ulong PackKey (byte [] key) 
49         {
50                 ulong res = 0;
51                 for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
52                         res |= (ulong) key [i] << sh;
53                 }
54                 return res;
55         }
56
57         internal static byte [] UnpackKey (ulong key) 
58         {
59                 byte [] res = new byte [blockSizeByte];
60                 for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
61                         res [i] = (byte) (key >> sh);
62                 }
63                 return res;
64         }
65
66         // Ek(Ek(m)) = m
67         internal static ulong [] weakKeys = {
68                 0x0101010101010101, /* 0000000 0000000 */
69                 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
70                 0x1F1F1F1FE0E0E0E0, /* 0000000 FFFFFFF */
71                 0xE0E0E0E01F1F1F1F  /* FFFFFFF 0000000 */
72         };
73
74         // Ek1(Ek2(m)) = m
75         internal static ulong [] semiweakKeys = {
76                 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
77                 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
78                 0x01E001E001F101F1, 0xE001E001F101F101,
79                 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
80                 0x011F011F010E010E, 0x1F011F010E010E01,
81                 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
82         };
83
84         public static bool IsWeakKey (byte [] rgbKey)
85         {
86                 if (rgbKey.Length == (blockSizeByte >> 3))
87                         throw new CryptographicException ("Wrong Key Length");
88
89                 ulong lk = PackKey (rgbKey);
90                 foreach (ulong wk in weakKeys) {
91                         if (lk == wk) return true;
92                 }
93                 return false;
94         }
95
96         public static bool IsSemiWeakKey (byte [] rgbKey)
97         {
98                 if (rgbKey.Length == (blockSizeByte >> 3))
99                         throw new CryptographicException ("Wrong Key Length");
100
101                 ulong lk = PackKey (rgbKey);
102                 foreach (ulong swk in semiweakKeys) {
103                         if (lk == swk) return true;
104                 }
105                 return false;
106         }
107
108         public override byte[] Key {
109                 get {
110                         if (KeyValue == null) {
111                                 // generate keys as long as we get weak or semi-weak keys
112                                 GenerateKey ();
113                                 while (IsWeakKey (KeyValue) || IsSemiWeakKey (KeyValue))
114                                         GenerateKey ();
115                         }
116                         return (byte[]) KeyValue.Clone ();
117                 }
118                 set {
119                         if (value == null)
120                                 throw new ArgumentNullException ();
121                         if (IsWeakKey (value) || IsSemiWeakKey (value))
122                                 throw new CryptographicException ();
123
124                         KeyValue = (byte[]) value.Clone ();
125                 }
126         }
127
128 } // DES
129
130 } // System.Security.Cryptography