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 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Globalization;
37 using System.Security.Cryptography;
40 // a. FIPS PUB 46-3: Data Encryption Standard
41 // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
43 namespace System.Security.Cryptography {
45 public abstract class DES : SymmetricAlgorithm {
47 const int blockSizeByte = 8;
53 FeedbackSizeValue = 64;
55 LegalKeySizesValue = new KeySizes[1];
56 LegalKeySizesValue[0] = new KeySizes(64, 64, 0);
58 LegalBlockSizesValue = new KeySizes[1];
59 LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);
62 public static new DES Create ()
64 return Create ("System.Security.Cryptography.DES");
67 public static new DES Create (string algo)
69 return (DES) CryptoConfig.CreateFromName (algo);
72 internal static ulong PackKey (byte[] key)
74 byte[] paritySetKey = new byte [blockSizeByte];
75 // adapted from bouncycastle - see bouncycastle.txt
76 for (int i=0; i < key.Length; i++) {
78 paritySetKey [i] = (byte)((b & 0xfe) |
79 ((((b >> 1) ^ (b >> 2) ^ (b >> 3) ^ (b >> 4) ^
80 (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01) & 0x01));
84 for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
85 res |= (ulong) paritySetKey [i] << sh;
88 Array.Clear (paritySetKey, 0, paritySetKey.Length);
93 internal static readonly ulong[] weakKeys = {
94 0x0101010101010101, /* 0000000 0000000 */
95 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
96 0x1F1F1F1F0E0E0E0E, /* 0000000 FFFFFFF */
97 0xE0E0E0E0F1F1F1F1 /* FFFFFFF 0000000 */
101 internal static readonly ulong[] semiweakKeys = {
102 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
103 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
104 0x01E001E001F101F1, 0xE001E001F101F101,
105 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
106 0x011F011F010E010E, 0x1F011F010E010E01,
107 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
110 public static bool IsWeakKey (byte[] rgbKey)
112 if (rgbKey.Length != blockSizeByte)
113 throw new CryptographicException (Locale.GetText ("Wrong Key Length"));
115 ulong lk = PackKey (rgbKey);
116 foreach (ulong wk in weakKeys) {
123 public static bool IsSemiWeakKey (byte[] rgbKey)
125 if (rgbKey.Length != blockSizeByte)
126 throw new CryptographicException (Locale.GetText ("Wrong Key Length"));
128 ulong lk = PackKey (rgbKey);
129 foreach (ulong swk in semiweakKeys) {
136 public override byte[] Key {
138 if (KeyValue == null) {
139 // GenerateKey is responsible to return a valid key
140 // e.g. no weak or semi-weak keys
143 return (byte[]) KeyValue.Clone ();
147 throw new ArgumentNullException ("Key");
148 if (value.Length != blockSizeByte)
149 throw new ArgumentException (Locale.GetText ("Wrong Key Length"));
150 if (IsWeakKey (value))
151 throw new CryptographicException (Locale.GetText ("Weak Key"));
152 if (IsSemiWeakKey (value))
153 throw new CryptographicException (Locale.GetText ("Semi Weak Key"));
155 KeyValue = (byte[]) value.Clone ();