3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
13 namespace System.Security.Cryptography {
15 using System.Diagnostics.Contracts;
17 [System.Runtime.InteropServices.ComVisible(true)]
18 public abstract class DES : SymmetricAlgorithm
20 private static KeySizes[] s_legalBlockSizes = {
21 new KeySizes(64, 64, 0)
23 private static KeySizes[] s_legalKeySizes = {
24 new KeySizes(64, 64, 0)
28 // protected constructors
34 FeedbackSizeValue = BlockSizeValue;
35 LegalBlockSizesValue = s_legalBlockSizes;
36 LegalKeySizesValue = s_legalKeySizes;
43 public override byte[] Key {
45 if (KeyValue == null) {
46 // Never hand back a weak or semi-weak key
49 } while (IsWeakKey(KeyValue) || IsSemiWeakKey(KeyValue));
51 return (byte[]) KeyValue.Clone();
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"));
59 if (IsWeakKey(value)) {
60 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"DES");
62 if (IsSemiWeakKey(value)) {
63 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_SemiWeak"),"DES");
65 KeyValue = (byte[]) value.Clone();
66 KeySizeValue = value.Length * 8;
74 new static public DES Create() {
76 return new System.Security.Cryptography.DESCryptoServiceProvider ();
78 return Create("System.Security.Cryptography.DES");
82 new static public DES Create(String algName) {
83 return (DES) CryptoConfig.CreateFromName(algName);
86 public static bool IsWeakKey(byte[] rgbKey) {
87 if (!IsLegalKeySize(rgbKey)) {
88 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
90 byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
91 UInt64 key = QuadWordFromBigEndian(rgbOddParityKey);
92 if ((key == 0x0101010101010101) ||
93 (key == 0xfefefefefefefefe) ||
94 (key == 0x1f1f1f1f0e0e0e0e) ||
95 (key == 0xe0e0e0e0f1f1f1f1)) {
101 public static bool IsSemiWeakKey(byte[] rgbKey) {
102 if (!IsLegalKeySize(rgbKey)) {
103 throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
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)) {
128 private static bool IsLegalKeySize(byte[] rgbKey) {
129 if (rgbKey != null && rgbKey.Length == 8) return(true);
133 private static UInt64 QuadWordFromBigEndian(byte[] block)
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])