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 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System
.Globalization
;
33 using System
.Security
.Cryptography
;
36 // a. FIPS PUB 46-3: Data Encryption Standard
37 // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
39 namespace System
.Security
.Cryptography
{
41 public abstract class DES
: SymmetricAlgorithm
{
43 const int blockSizeByte
= 8;
49 FeedbackSizeValue
= 8;
51 LegalKeySizesValue
= new KeySizes
[1];
52 LegalKeySizesValue
[0] = new KeySizes(64, 64, 0);
54 LegalBlockSizesValue
= new KeySizes
[1];
55 LegalBlockSizesValue
[0] = new KeySizes(64, 64, 0);
58 public static new DES
Create ()
60 return Create ("System.Security.Cryptography.DES");
63 public static new DES
Create (string algo
)
65 return (DES
) CryptoConfig
.CreateFromName (algo
);
68 internal static ulong PackKey (byte[] key
)
70 byte[] paritySetKey
= new byte [blockSizeByte
];
71 // adapted from bouncycastle - see bouncycastle.txt
72 for (int i
=0; i
< key
.Length
; i
++) {
74 paritySetKey
[i
] = (byte)((b
& 0xfe) |
75 ((((b
>> 1) ^
(b
>> 2) ^
(b
>> 3) ^
(b
>> 4) ^
76 (b
>> 5) ^
(b
>> 6) ^
(b
>> 7)) ^
0x01) & 0x01));
80 for (int i
= 0, sh
= 8*blockSizeByte
; (sh
= sh
- 8) >= 0; i
++) {
81 res
|= (ulong) paritySetKey
[i
] << sh
;
84 Array
.Clear (paritySetKey
, 0, paritySetKey
.Length
);
89 internal static readonly ulong[] weakKeys
= {
90 0x0101010101010101, /* 0000000 0000000 */
91 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
92 0x1F1F1F1F0E0E0E0E, /* 0000000 FFFFFFF */
93 0xE0E0E0E0F1F1F1F1 /* FFFFFFF 0000000 */
97 internal static readonly ulong[] semiweakKeys
= {
98 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
99 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
100 0x01E001E001F101F1, 0xE001E001F101F101,
101 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
102 0x011F011F010E010E, 0x1F011F010E010E01,
103 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
106 public static bool IsWeakKey (byte[] rgbKey
)
108 if (rgbKey
.Length
!= blockSizeByte
)
109 throw new CryptographicException (Locale
.GetText ("Wrong Key Length"));
111 ulong lk
= PackKey (rgbKey
);
112 foreach (ulong wk
in weakKeys
) {
119 public static bool IsSemiWeakKey (byte[] rgbKey
)
121 if (rgbKey
.Length
!= blockSizeByte
)
122 throw new CryptographicException (Locale
.GetText ("Wrong Key Length"));
124 ulong lk
= PackKey (rgbKey
);
125 foreach (ulong swk
in semiweakKeys
) {
132 public override byte[] Key
{
134 if (KeyValue
== null) {
135 // GenerateKey is responsible to return a valid key
136 // e.g. no weak or semi-weak keys
139 return (byte[]) KeyValue
.Clone ();
143 throw new ArgumentNullException ("Key");
144 if (value.Length
!= blockSizeByte
)
145 throw new ArgumentException (Locale
.GetText ("Wrong Key Length"));
146 if (IsWeakKey (value))
147 throw new CryptographicException (Locale
.GetText ("Weak Key"));
148 if (IsSemiWeakKey (value))
149 throw new CryptographicException (Locale
.GetText ("Semi Weak Key"));
151 KeyValue
= (byte[]) value.Clone ();