2 // System.Security.Cryptography.DES
5 // Sergey Chaban (serge@wildwestsoftware.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
9 // (C) 2004 Novell (http://www.novell.com)
13 using System.Security.Cryptography;
16 // a. FIPS PUB 46-3: Data Encryption Standard
17 // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
19 namespace System.Security.Cryptography {
21 public abstract class DES : SymmetricAlgorithm {
23 private static int blockSizeByte = 8;
29 FeedbackSizeValue = 64;
31 LegalKeySizesValue = new KeySizes[1];
32 LegalKeySizesValue[0] = new KeySizes(64, 64, 0);
34 LegalBlockSizesValue = new KeySizes[1];
35 LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);
38 public static new DES Create ()
40 return Create ("System.Security.Cryptography.DES");
43 public static new DES Create (string algo)
45 return (DES) CryptoConfig.CreateFromName (algo);
48 internal static ulong PackKey (byte [] key)
51 for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
52 res |= (ulong) key [i] << sh;
57 internal static byte [] UnpackKey (ulong key)
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);
67 internal static ulong [] weakKeys = {
68 0x0101010101010101, /* 0000000 0000000 */
69 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
70 0x1F1F1F1FE0E0E0E0, /* 0000000 FFFFFFF */
71 0xE0E0E0E01F1F1F1F /* FFFFFFF 0000000 */
75 internal static ulong [] semiweakKeys = {
76 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
77 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
78 0x01E001E001F101F1, 0xE001E001F101F101,
79 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
80 0x011F011F010E010E, 0x1F011F010E010E01,
81 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
84 public static bool IsWeakKey (byte [] rgbKey)
86 if (rgbKey.Length == (blockSizeByte >> 3))
87 throw new CryptographicException ("Wrong Key Length");
89 ulong lk = PackKey (rgbKey);
90 foreach (ulong wk in weakKeys) {
91 if (lk == wk) return true;
96 public static bool IsSemiWeakKey (byte [] rgbKey)
98 if (rgbKey.Length == (blockSizeByte >> 3))
99 throw new CryptographicException ("Wrong Key Length");
101 ulong lk = PackKey (rgbKey);
102 foreach (ulong swk in semiweakKeys) {
103 if (lk == swk) return true;
108 public override byte[] Key {
110 if (KeyValue == null) {
111 // generate keys as long as we get weak or semi-weak keys
113 while (IsWeakKey (KeyValue) || IsSemiWeakKey (KeyValue))
116 return (byte[]) KeyValue.Clone ();
120 throw new ArgumentNullException ();
121 if (IsWeakKey (value) || IsSemiWeakKey (value))
122 throw new CryptographicException ();
124 KeyValue = (byte[]) value.Clone ();
130 } // System.Security.Cryptography