1 package org.bouncycastle.crypto.params;
2 
3 public class DESParameters
4     extends KeyParameter
5 {
DESParameters( byte[] key)6     public DESParameters(
7         byte[]  key)
8     {
9         super(key);
10 
11         if (isWeakKey(key, 0))
12         {
13             throw new IllegalArgumentException("attempt to create weak DES key");
14         }
15     }
16 
17     /*
18      * DES Key length in bytes.
19      */
20     static public final int DES_KEY_LENGTH = 8;
21 
22     /*
23      * Table of weak and semi-weak keys taken from Schneier pp281
24      */
25     static private final int N_DES_WEAK_KEYS = 16;
26 
27     static private byte[] DES_weak_keys =
28     {
29         /* weak keys */
30         (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
31         (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
32         (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
33         (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,
34 
35         /* semi-weak keys */
36         (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
37         (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
38         (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
39         (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
40         (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
41         (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
42         (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
43         (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
44         (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
45         (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
46         (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
47         (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
48     };
49 
50     /**
51      * DES has 16 weak keys.  This method will check
52      * if the given DES key material is weak or semi-weak.
53      * Key material that is too short is regarded as weak.
54      * <p>
55      * See <a href="http://www.counterpane.com/applied.html">"Applied
56      * Cryptography"</a> by Bruce Schneier for more information.
57      *
58      * @return true if the given DES key material is weak or semi-weak,
59      *     false otherwise.
60      */
isWeakKey( byte[] key, int offset)61     public static boolean isWeakKey(
62         byte[] key,
63         int offset)
64     {
65         if (key.length - offset < DES_KEY_LENGTH)
66         {
67             throw new IllegalArgumentException("key material too short.");
68         }
69 
70         nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++)
71         {
72             for (int j = 0; j < DES_KEY_LENGTH; j++)
73             {
74                 if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j])
75                 {
76                     continue nextkey;
77                 }
78             }
79 
80             return true;
81         }
82         return false;
83     }
84 
85     /**
86      * DES Keys use the LSB as the odd parity bit.  This can
87      * be used to check for corrupt keys.
88      *
89      * @param bytes the byte array to set the parity on.
90      */
setOddParity( byte[] bytes)91     public static void setOddParity(
92         byte[] bytes)
93     {
94         for (int i = 0; i < bytes.length; i++)
95         {
96             int b = bytes[i];
97             bytes[i] = (byte)((b & 0xfe) |
98                             ((((b >> 1) ^
99                             (b >> 2) ^
100                             (b >> 3) ^
101                             (b >> 4) ^
102                             (b >> 5) ^
103                             (b >> 6) ^
104                             (b >> 7)) ^ 0x01) & 0x01));
105         }
106     }
107 }
108