View Javadoc
1   package org.bouncycastle.crypto.params;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * SNMP Java Client
6    * ჻჻჻჻჻჻
7    * Copyright 2023 Sentry Software, Westhawk
8    * ჻჻჻჻჻჻
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23   */
24  
25  public class DESParameters
26      extends KeyParameter
27  {
28      public DESParameters(
29          byte[]  key)
30      {
31          super(key);
32  
33          if (isWeakKey(key, 0))
34          {
35              throw new IllegalArgumentException("attempt to create weak DES key");
36          }
37      }
38  
39      /*
40       * DES Key length in bytes.
41       */
42      static public final int DES_KEY_LENGTH = 8;
43  
44      /*
45       * Table of weak and semi-weak keys taken from Schneier pp281
46       */
47      static private final int N_DES_WEAK_KEYS = 16;
48  
49      static private byte[] DES_weak_keys =
50      {
51          /* weak keys */
52          (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
53          (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
54          (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
55          (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,
56  
57          /* semi-weak keys */
58          (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
59          (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
60          (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
61          (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
62          (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
63          (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
64          (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
65          (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
66          (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
67          (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
68          (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
69          (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
70      };
71  
72      /**
73       * DES has 16 weak keys.  This method will check
74       * if the given DES key material is weak or semi-weak.
75       * Key material that is too short is regarded as weak.
76       * <p>
77       * See <a href="http://www.counterpane.com/applied.html">"Applied
78       * Cryptography"</a> by Bruce Schneier for more information.
79       *
80       * @return true if the given DES key material is weak or semi-weak,
81       *     false otherwise.
82       */
83      public static boolean isWeakKey(
84          byte[] key,
85          int offset)
86      {
87          if (key.length - offset < DES_KEY_LENGTH)
88          {
89              throw new IllegalArgumentException("key material too short.");
90          }
91  
92          nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++)
93          {
94              for (int j = 0; j < DES_KEY_LENGTH; j++)
95              {
96                  if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j])
97                  {
98                      continue nextkey;
99                  }
100             }
101 
102             return true;
103         }
104         return false;
105     }
106 
107     /**
108      * DES Keys use the LSB as the odd parity bit.  This can
109      * be used to check for corrupt keys.
110      *
111      * @param bytes the byte array to set the parity on.
112      */
113     public static void setOddParity(
114         byte[] bytes)
115     {
116         for (int i = 0; i < bytes.length; i++)
117         {
118             int b = bytes[i];
119             bytes[i] = (byte)((b & 0xfe) |
120                             ((((b >> 1) ^
121                             (b >> 2) ^
122                             (b >> 3) ^
123                             (b >> 4) ^
124                             (b >> 5) ^
125                             (b >> 6) ^
126                             (b >> 7)) ^ 0x01) & 0x01));
127         }
128     }
129 }