001: package org.bouncycastle.crypto.params;
002:
003: public class DESParameters extends KeyParameter {
004: public DESParameters(byte[] key) {
005: super (key);
006:
007: if (isWeakKey(key, 0)) {
008: throw new IllegalArgumentException(
009: "attempt to create weak DES key");
010: }
011: }
012:
013: /*
014: * DES Key length in bytes.
015: */
016: static public final int DES_KEY_LENGTH = 8;
017:
018: /*
019: * Table of weak and semi-weak keys taken from Schneier pp281
020: */
021: static private final int N_DES_WEAK_KEYS = 16;
022:
023: static private byte[] DES_weak_keys = {
024: /* weak keys */
025: (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
026: (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x1f,
027: (byte) 0x1f, (byte) 0x1f, (byte) 0x1f, (byte) 0x0e,
028: (byte) 0x0e, (byte) 0x0e, (byte) 0x0e, (byte) 0xe0,
029: (byte) 0xe0, (byte) 0xe0, (byte) 0xe0, (byte) 0xf1,
030: (byte) 0xf1, (byte) 0xf1, (byte) 0xf1, (byte) 0xfe,
031: (byte) 0xfe, (byte) 0xfe, (byte) 0xfe, (byte) 0xfe,
032: (byte) 0xfe, (byte) 0xfe, (byte) 0xfe,
033:
034: /* semi-weak keys */
035: (byte) 0x01, (byte) 0xfe, (byte) 0x01, (byte) 0xfe,
036: (byte) 0x01, (byte) 0xfe, (byte) 0x01, (byte) 0xfe,
037: (byte) 0x1f, (byte) 0xe0, (byte) 0x1f, (byte) 0xe0,
038: (byte) 0x0e, (byte) 0xf1, (byte) 0x0e, (byte) 0xf1,
039: (byte) 0x01, (byte) 0xe0, (byte) 0x01, (byte) 0xe0,
040: (byte) 0x01, (byte) 0xf1, (byte) 0x01, (byte) 0xf1,
041: (byte) 0x1f, (byte) 0xfe, (byte) 0x1f, (byte) 0xfe,
042: (byte) 0x0e, (byte) 0xfe, (byte) 0x0e, (byte) 0xfe,
043: (byte) 0x01, (byte) 0x1f, (byte) 0x01, (byte) 0x1f,
044: (byte) 0x01, (byte) 0x0e, (byte) 0x01, (byte) 0x0e,
045: (byte) 0xe0, (byte) 0xfe, (byte) 0xe0, (byte) 0xfe,
046: (byte) 0xf1, (byte) 0xfe, (byte) 0xf1, (byte) 0xfe,
047: (byte) 0xfe, (byte) 0x01, (byte) 0xfe, (byte) 0x01,
048: (byte) 0xfe, (byte) 0x01, (byte) 0xfe, (byte) 0x01,
049: (byte) 0xe0, (byte) 0x1f, (byte) 0xe0, (byte) 0x1f,
050: (byte) 0xf1, (byte) 0x0e, (byte) 0xf1, (byte) 0x0e,
051: (byte) 0xe0, (byte) 0x01, (byte) 0xe0, (byte) 0x01,
052: (byte) 0xf1, (byte) 0x01, (byte) 0xf1, (byte) 0x01,
053: (byte) 0xfe, (byte) 0x1f, (byte) 0xfe, (byte) 0x1f,
054: (byte) 0xfe, (byte) 0x0e, (byte) 0xfe, (byte) 0x0e,
055: (byte) 0x1f, (byte) 0x01, (byte) 0x1f, (byte) 0x01,
056: (byte) 0x0e, (byte) 0x01, (byte) 0x0e, (byte) 0x01,
057: (byte) 0xfe, (byte) 0xe0, (byte) 0xfe, (byte) 0xe0,
058: (byte) 0xfe, (byte) 0xf1, (byte) 0xfe, (byte) 0xf1 };
059:
060: /**
061: * DES has 16 weak keys. This method will check
062: * if the given DES key material is weak or semi-weak.
063: * Key material that is too short is regarded as weak.
064: * <p>
065: * See <a href="http://www.counterpane.com/applied.html">"Applied
066: * Cryptography"</a> by Bruce Schneier for more information.
067: *
068: * @return true if the given DES key material is weak or semi-weak,
069: * false otherwise.
070: */
071: public static boolean isWeakKey(byte[] key, int offset) {
072: if (key.length - offset < DES_KEY_LENGTH) {
073: throw new IllegalArgumentException(
074: "key material too short.");
075: }
076:
077: nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) {
078: for (int j = 0; j < DES_KEY_LENGTH; j++) {
079: if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH
080: + j]) {
081: continue nextkey;
082: }
083: }
084:
085: return true;
086: }
087: return false;
088: }
089:
090: /**
091: * DES Keys use the LSB as the odd parity bit. This can
092: * be used to check for corrupt keys.
093: *
094: * @param bytes the byte array to set the parity on.
095: */
096: public static void setOddParity(byte[] bytes) {
097: for (int i = 0; i < bytes.length; i++) {
098: int b = bytes[i];
099: bytes[i] = (byte) ((b & 0xfe) | ((((b >> 1) ^ (b >> 2)
100: ^ (b >> 3) ^ (b >> 4) ^ (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01) & 0x01));
101: }
102: }
103: }
|