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 javax.crypto.spec;
019:
020: import java.security.InvalidKeyException;
021: import java.security.spec.KeySpec;
022:
023: import org.apache.harmony.crypto.internal.nls.Messages;
024:
025: /**
026: * @com.intel.drl.spec_ref
027: */
028: public class DESKeySpec implements KeySpec {
029:
030: /**
031: * @com.intel.drl.spec_ref
032: */
033: public static final int DES_KEY_LEN = 8;
034:
035: private final byte[] key;
036:
037: // DES weak and semi-weak keys
038: // Got from:
039: // FIP PUB 74
040: // FEDERAL INFORMATION PROCESSING STANDARDS PUBLICATION 1981
041: // GUIDELINES FOR IMPLEMENTING AND USING THE NBS DATA ENCRYPTION STANDARD
042: // http://www.dice.ucl.ac.be/crypto/standards/fips/fip74/fip74-1.pdf
043: private static final byte[][] SEMIWEAKS = {
044: { (byte) 0xE0, (byte) 0x01, (byte) 0xE0, (byte) 0x01,
045: (byte) 0xF1, (byte) 0x01, (byte) 0xF1, (byte) 0x01 },
046:
047: { (byte) 0x01, (byte) 0xE0, (byte) 0x01, (byte) 0xE0,
048: (byte) 0x01, (byte) 0xF1, (byte) 0x01, (byte) 0xF1 },
049:
050: { (byte) 0xFE, (byte) 0x1F, (byte) 0xFE, (byte) 0x1F,
051: (byte) 0xFE, (byte) 0x0E, (byte) 0xFE, (byte) 0x0E },
052:
053: { (byte) 0x1F, (byte) 0xFE, (byte) 0x1F, (byte) 0xFE,
054: (byte) 0x0E, (byte) 0xFE, (byte) 0x0E, (byte) 0xFE },
055:
056: { (byte) 0xE0, (byte) 0x1F, (byte) 0xE0, (byte) 0x1F,
057: (byte) 0xF1, (byte) 0x0E, (byte) 0xF1, (byte) 0x0E },
058:
059: { (byte) 0x1F, (byte) 0xE0, (byte) 0x1F, (byte) 0xE0,
060: (byte) 0x0E, (byte) 0xF1, (byte) 0x0E, (byte) 0xF1 },
061:
062: { (byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE,
063: (byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE },
064:
065: { (byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01,
066: (byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01 },
067:
068: { (byte) 0x01, (byte) 0x1F, (byte) 0x01, (byte) 0x1F,
069: (byte) 0x01, (byte) 0x0E, (byte) 0x01, (byte) 0x0E },
070:
071: { (byte) 0x1F, (byte) 0x01, (byte) 0x1F, (byte) 0x01,
072: (byte) 0x0E, (byte) 0x01, (byte) 0x0E, (byte) 0x01 },
073:
074: { (byte) 0xE0, (byte) 0xFE, (byte) 0xE0, (byte) 0xFE,
075: (byte) 0xF1, (byte) 0xFE, (byte) 0xF1, (byte) 0xFE },
076:
077: { (byte) 0xFE, (byte) 0xE0, (byte) 0xFE, (byte) 0xE0,
078: (byte) 0xFE, (byte) 0xF1, (byte) 0xFE, (byte) 0xF1 },
079:
080: { (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
081: (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 },
082:
083: { (byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE,
084: (byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE },
085:
086: { (byte) 0xE0, (byte) 0xE0, (byte) 0xE0, (byte) 0xE0,
087: (byte) 0xF1, (byte) 0xF1, (byte) 0xF1, (byte) 0xF1 },
088:
089: { (byte) 0x1F, (byte) 0x1F, (byte) 0x1F, (byte) 0x1F,
090: (byte) 0x0E, (byte) 0x0E, (byte) 0x0E, (byte) 0x0E },
091:
092: };
093:
094: /**
095: * @com.intel.drl.spec_ref
096: */
097: public DESKeySpec(byte[] key) throws InvalidKeyException {
098: this (key, 0);
099: }
100:
101: /**
102: * @com.intel.drl.spec_ref
103: */
104: public DESKeySpec(byte[] key, int offset)
105: throws InvalidKeyException {
106: if (key == null) {
107: throw new NullPointerException(Messages
108: .getString("crypto.2F")); //$NON-NLS-1$
109: }
110: if (key.length - offset < DES_KEY_LEN) {
111: throw new InvalidKeyException(Messages
112: .getString("crypto.40")); //$NON-NLS-1$
113: }
114: this .key = new byte[DES_KEY_LEN];
115: System.arraycopy(key, offset, this .key, 0, DES_KEY_LEN);
116: }
117:
118: /**
119: * @com.intel.drl.spec_ref
120: */
121: public byte[] getKey() {
122: byte[] result = new byte[DES_KEY_LEN];
123: System.arraycopy(this .key, 0, result, 0, DES_KEY_LEN);
124: return result;
125: }
126:
127: /**
128: * @com.intel.drl.spec_ref
129: */
130: public static boolean isParityAdjusted(byte[] key, int offset)
131: throws InvalidKeyException {
132: if (key == null) {
133: throw new InvalidKeyException(Messages
134: .getString("crypto.2F")); //$NON-NLS-1$
135: }
136: if (key.length - offset < DES_KEY_LEN) {
137: throw new InvalidKeyException(Messages
138: .getString("crypto.40")); //$NON-NLS-1$
139: }
140:
141: int byteKey = 0;
142:
143: for (int i = offset; i < DES_KEY_LEN; i++) {
144: byteKey = key[i];
145:
146: byteKey ^= byteKey >> 1;
147: byteKey ^= byteKey >> 2;
148: byteKey ^= byteKey >> 4;
149:
150: if ((byteKey & 1) == 0) {
151: return false;
152: }
153: }
154: return true;
155: }
156:
157: /**
158: * @com.intel.drl.spec_ref
159: */
160: public static boolean isWeak(byte[] key, int offset)
161: throws InvalidKeyException {
162: if (key == null) {
163: throw new InvalidKeyException(Messages
164: .getString("crypto.2F")); //$NON-NLS-1$
165: }
166: if (key.length - offset < DES_KEY_LEN) {
167: throw new InvalidKeyException(Messages
168: .getString("crypto.40")); //$NON-NLS-1$
169: }
170: I: for (int i = 0; i < SEMIWEAKS.length; i++) {
171: for (int j = 0; j < DES_KEY_LEN; j++) {
172: if (SEMIWEAKS[i][j] != key[offset + j]) {
173: continue I;
174: }
175: }
176: return true;
177: }
178: return false;
179: }
180: }
|