summary refs log tree commit diff
path: root/crypto/src/crypto/parameters/DesParameters.cs
blob: a1f67e2b11cb8a0663285b638e601bd4e7aa55cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;

namespace Org.BouncyCastle.Crypto.Parameters
{
    public class DesParameters
		: KeyParameter
    {
        public DesParameters(
            byte[] key)
			: base(key)
        {
            if (IsWeakKey(key))
				throw new ArgumentException("attempt to create weak DES key");
        }

		public DesParameters(
			byte[]	key,
			int		keyOff,
			int		keyLen)
			: base(key, keyOff, keyLen)
		{
			if (IsWeakKey(key, keyOff))
				throw new ArgumentException("attempt to create weak DES key");
		}

		/*
        * DES Key Length in bytes.
        */
        public const int DesKeyLength = 8;

        /*
        * Table of weak and semi-weak keys taken from Schneier pp281
        */
        private const int N_DES_WEAK_KEYS = 16;

        private static readonly byte[] DES_weak_keys =
        {
            /* weak keys */
            (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
            (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
            (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
            (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,

            /* semi-weak keys */
            (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
            (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
            (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
            (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
            (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
            (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
            (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
            (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
            (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
            (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
            (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
            (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
        };

        /**
        * DES has 16 weak keys.  This method will check
        * if the given DES key material is weak or semi-weak.
        * Key material that is too short is regarded as weak.
        * <p>
        * See <a href="http://www.counterpane.com/applied.html">"Applied
        * Cryptography"</a> by Bruce Schneier for more information.
        * </p>
        * @return true if the given DES key material is weak or semi-weak,
        *     false otherwise.
        */
        public static bool IsWeakKey(
            byte[]	key,
            int		offset)
        {
            if (key.Length - offset < DesKeyLength)
                throw new ArgumentException("key material too short.");

			//nextkey:
            for (int i = 0; i < N_DES_WEAK_KEYS; i++)
            {
                bool unmatch = false;
                for (int j = 0; j < DesKeyLength; j++)
                {
                    if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j])
                    {
                        //continue nextkey;
                        unmatch = true;
						break;
                    }
                }

				if (!unmatch)
				{
					return true;
				}
            }

			return false;
        }

		public static bool IsWeakKey(
			byte[] key)
		{
			return IsWeakKey(key, 0);
		}

        public static byte SetOddParity(byte b)
        {
            uint parity = b ^ 1U;
            parity ^= (parity >> 4);
            parity ^= (parity >> 2);
            parity ^= (parity >> 1);
            parity &= 1U;

            return (byte)(b ^ parity);
        }

        /**
        * DES Keys use the LSB as the odd parity bit.  This can
        * be used to check for corrupt keys.
        *
        * @param bytes the byte array to set the parity on.
        */
        public static void SetOddParity(byte[] bytes)
        {
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = SetOddParity(bytes[i]);
            }
        }

        public static void SetOddParity(byte[] bytes, int off, int len)
        {
            for (int i = 0; i < len; i++)
            {
                bytes[off + i] = SetOddParity(bytes[off + i]);
            }
        }
    }
}