001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.util.crypto.params;
019
020 public class DESParameters
021 extends KeyParameter
022 {
023 public DESParameters(
024 byte[] key)
025 {
026 super(key);
027
028 if (isWeakKey(key, 0))
029 {
030 throw new IllegalArgumentException("attempt to create weak DES key");
031 }
032 }
033
034 /*
035 * DES Key length in bytes.
036 */
037 static public final int DES_KEY_LENGTH = 8;
038
039 /*
040 * Table of weak and semi-weak keys taken from Schneier pp281
041 */
042 static private final int N_DES_WEAK_KEYS = 16;
043
044 static private byte[] DES_weak_keys =
045 {
046 /* weak keys */
047 (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
048 (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
049 (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
050 (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,
051
052 /* semi-weak keys */
053 (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
054 (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
055 (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
056 (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
057 (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
058 (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
059 (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
060 (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
061 (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
062 (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
063 (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
064 (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
065 };
066
067 /**
068 * DES has 16 weak keys. This method will check
069 * if the given DES key material is weak or semi-weak.
070 * Key material that is too short is regarded as weak.
071 * <p>
072 * See <a href="http://www.counterpane.com/applied.html">"Applied
073 * Cryptography"</a> by Bruce Schneier for more information.
074 *
075 * @return true if the given DES key material is weak or semi-weak,
076 * false otherwise.
077 */
078 public static boolean isWeakKey(
079 byte[] key,
080 int offset)
081 {
082 if (key.length - offset < DES_KEY_LENGTH)
083 {
084 throw new IllegalArgumentException("key material too short.");
085 }
086
087 nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++)
088 {
089 for (int j = 0; j < DES_KEY_LENGTH; j++)
090 {
091 if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j])
092 {
093 continue nextkey;
094 }
095 }
096
097 return true;
098 }
099 return false;
100 }
101
102 /**
103 * DES Keys use the LSB as the odd parity bit. This can
104 * be used to check for corrupt keys.
105 *
106 * @param bytes the byte array to set the parity on.
107 */
108 public static void setOddParity(
109 byte[] bytes)
110 {
111 for (int i = 0; i < bytes.length; i++)
112 {
113 int b = bytes[i];
114 bytes[i] = (byte)((b & 0xfe) |
115 ((((b >> 1) ^
116 (b >> 2) ^
117 (b >> 3) ^
118 (b >> 4) ^
119 (b >> 5) ^
120 (b >> 6) ^
121 (b >> 7)) ^ 0x01) & 0x01));
122 }
123 }
124 }