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