summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorRaif S. Naffah <raif@swiftdsl.com.au>2006-07-21 23:10:27 +0000
committerRaif S. Naffah <raif@swiftdsl.com.au>2006-07-21 23:10:27 +0000
commit33e51584f976c04344b1cff1536694140d31ea55 (patch)
treeacda1d1d7ee70145525d70423b28e2ba0ab16e64 /gnu
parented4ca6d45cc58fbb859b8a86ce4241d2bfdadedc (diff)
downloadclasspath-33e51584f976c04344b1cff1536694140d31ea55.tar.gz
2006-07-22 Raif S. Naffah <raif@swiftdsl.com.au>
PR Classpath/28100 * gnu/javax/crypto/cipher/TripleDES.java: Updated documentation. (KEY_SIZE): Likewise. (adjustParity(int,byte[],int): New method. (adjustParity(byte[],int): Call above method with 3 as 1st argument. (isParityAdjusted(int,byte[],int)): New method. (isParityAdjusted): Call above method with 3 as 1st argument. (keySizes): Add 8 and 16 as other valid key sizes. (makeKey): Amended to cater for 1, 2 and 3 independent DES keys.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/javax/crypto/cipher/TripleDES.java132
1 files changed, 105 insertions, 27 deletions
diff --git a/gnu/javax/crypto/cipher/TripleDES.java b/gnu/javax/crypto/cipher/TripleDES.java
index 7aeb4ea96..1e98bfc83 100644
--- a/gnu/javax/crypto/cipher/TripleDES.java
+++ b/gnu/javax/crypto/cipher/TripleDES.java
@@ -40,17 +40,21 @@ package gnu.javax.crypto.cipher;
import gnu.java.security.Registry;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.security.InvalidKeyException;
/**
* Triple-DES, 3DES, or DESede is a <i>combined cipher</i> that uses three
- * iterations of the Data Encryption Standard cipher to improve the security (at
- * the cost of speed) of plain DES.
+ * iterations of the Data Encryption Standard cipher to theoretically improve
+ * the security of plain DES, at the cost of speed.
* <p>
- * Triple-DES runs the DES algorithm three times with three independent 56 bit
- * keys. To encrypt:
+ * Triple-DES runs the DES algorithm three times with one, two or three
+ * independent 56-bit (DES) keys. When used with one DES key, the cipher behaves
+ * exactly like a (slower) DES.
+ * <p>
+ * To encrypt:
* <blockquote><i>C<sub>i</sub> = E<sub>k3</sub> ( E<sub>k2</sub><sup>-1</sup> (
* E<sub>k1</sub> ( P<sub>i</sub> )))</i>
* </blockquote>
@@ -75,10 +79,8 @@ public class TripleDES
{
/** Triple-DES only operates on 64 bit blocks. */
public static final int BLOCK_SIZE = 8;
-
- /** Triple-DES uses 168 bits of a parity-adjusted 192 bit key. */
+ /** By default, Triple-DES uses 168 bits of a parity-adjusted 192 bit key. */
public static final int KEY_SIZE = 24;
-
/** The underlying DES instance. */
private DES des;
@@ -92,21 +94,45 @@ public class TripleDES
}
/**
- * Transform a key so it will be parity adjusted.
+ * Convenience method which calls the method with same name and three
+ * arguments, passing <code>3</code> as the value of the first parameter.
*
* @param kb The key bytes to adjust.
* @param offset The starting offset into the key bytes.
- * @see DES#adjustParity(byte[],int)
*/
public static void adjustParity(byte[] kb, int offset)
{
+ adjustParity(3, kb, offset);
+ }
+
+ /**
+ * Adjusts, in-situ, the parity of the designated bytes, so they can be used
+ * as DES keys for a 3-DES 1-, 2- or 3-key cipher.
+ *
+ * @param keyCount the number of independent DES keys. Can be either
+ * <code>1</code>, <code>2</code> or <code>3</code>. Any other value
+ * will cause an {@link IllegalArgumentException} to be raised.
+ * @param kb the array containing the key bytes to adjust. MUST have at least
+ * <code>8 * keyCount</code> bytes starting at offset position
+ * <code>offset</code>, otherwise an
+ * {@link ArrayIndexOutOfBoundsException} will be raised.
+ * @param offset the starting offset into the array.
+ * @see DES#adjustParity(byte[],int)
+ */
+ public static void adjustParity(int keyCount, byte[] kb, int offset)
+ {
+ if (keyCount < 1 || keyCount > 3)
+ throw new IllegalArgumentException("Invalid keyCount value: " + keyCount);
DES.adjustParity(kb, offset);
- DES.adjustParity(kb, offset + 8);
- DES.adjustParity(kb, offset + 16);
+ if (keyCount > 1)
+ DES.adjustParity(kb, offset + 8);
+ if (keyCount > 2)
+ DES.adjustParity(kb, offset + 16);
}
/**
- * Tests if a byte array has already been parity adjusted.
+ * Convenience method which calls the method with same name and three
+ * arguments, passing <code>3</code> as the value of the first parameter.
*
* @param kb The key bytes to test.
* @param offset The starting offset into the key bytes.
@@ -117,9 +143,37 @@ public class TripleDES
*/
public static boolean isParityAdjusted(byte[] kb, int offset)
{
- return DES.isParityAdjusted(kb, offset)
- && DES.isParityAdjusted(kb, offset + 8)
- && DES.isParityAdjusted(kb, offset + 16);
+ return isParityAdjusted(3, kb, offset);
+ }
+
+ /**
+ * Tests if enough bytes, expected to be used as DES keys for a 3-DES 1-, 2-
+ * or 3-key cipher, located in a designated byte array, has already been
+ * parity adjusted.
+ *
+ * @param keyCount the number of independent DES keys. Can be either
+ * <code>1</code>, <code>2</code> or <code>3</code>. Any other value
+ * will cause an {@link IllegalArgumentException} to be raised.
+ * @param kb the array containing the key bytes to test. MUST have at least
+ * <code>8 * keyCount</code> bytes starting at offset position
+ * <code>offset</code>, otherwise an
+ * {@link ArrayIndexOutOfBoundsException} will be raised.
+ * @param offset the starting offset into the array.
+ * @return <code>true</code> if the bytes in <i>kb</i> starting at
+ * <i>offset</i> are parity adjusted.
+ * @see DES#isParityAdjusted(byte[],int)
+ * @see #adjustParity(int,byte[],int)
+ */
+ public static boolean isParityAdjusted(int keyCount, byte[] kb, int offset)
+ {
+ if (keyCount < 1 || keyCount > 3)
+ throw new IllegalArgumentException("Invalid keyCount value: " + keyCount);
+ boolean result = DES.isParityAdjusted(kb, offset);
+ if (keyCount > 1)
+ result = result && DES.isParityAdjusted(kb, offset + 8);
+ if (keyCount > 2)
+ result = result && DES.isParityAdjusted(kb, offset + 16);
+ return result;
}
public Object clone()
@@ -134,25 +188,49 @@ public class TripleDES
public Iterator keySizes()
{
- return Collections.singleton(Integer.valueOf(KEY_SIZE)).iterator();
+ ArrayList al = new ArrayList();
+ al.add(Integer.valueOf(8));
+ al.add(Integer.valueOf(16));
+ al.add(Integer.valueOf(24));
+ return Collections.unmodifiableList(al).iterator();
}
public Object makeKey(byte[] kb, int bs) throws InvalidKeyException
{
- if (kb.length != KEY_SIZE)
- throw new InvalidKeyException("TripleDES key must be 24 bytes");
- if (! isParityAdjusted(kb, 0))
- adjustParity(kb, 0);
+ if (kb.length != 8 && kb.length != 16 && kb.length != 24)
+ throw new InvalidKeyException("TripleDES key must be 8, 16 or 24 bytes: "
+ + kb.length);
+ Context ctx = new Context();
byte[] k1 = new byte[DES.KEY_SIZE];
- byte[] k2 = new byte[DES.KEY_SIZE];
- byte[] k3 = new byte[DES.KEY_SIZE];
System.arraycopy(kb, 0, k1, 0, DES.KEY_SIZE);
- System.arraycopy(kb, DES.KEY_SIZE, k2, 0, DES.KEY_SIZE);
- System.arraycopy(kb, 2 * DES.KEY_SIZE, k3, 0, DES.KEY_SIZE);
- Context ctx = new Context();
+ if (! DES.isParityAdjusted(k1, 0))
+ DES.adjustParity(k1, 0);
ctx.k1 = (DES.Context) des.makeKey(k1, bs);
- ctx.k2 = (DES.Context) des.makeKey(k2, bs);
- ctx.k3 = (DES.Context) des.makeKey(k3, bs);
+
+ if (kb.length == 8)
+ {
+ ctx.k2 = (DES.Context) des.makeKey(k1, bs);
+ ctx.k3 = (DES.Context) des.makeKey(k1, bs);
+ }
+ else
+ {
+ byte[] k2 = new byte[DES.KEY_SIZE];
+ System.arraycopy(kb, DES.KEY_SIZE, k2, 0, DES.KEY_SIZE);
+ if (! DES.isParityAdjusted(k2, 0))
+ DES.adjustParity(k2, 0);
+ ctx.k2 = (DES.Context) des.makeKey(k2, bs);
+
+ byte[] k3 = new byte[DES.KEY_SIZE];
+ if (kb.length == 16)
+ ctx.k3 = (DES.Context) des.makeKey(k1, bs);
+ else
+ {
+ System.arraycopy(kb, 2 * DES.KEY_SIZE, k3, 0, DES.KEY_SIZE);
+ if (! DES.isParityAdjusted(k3, 0))
+ DES.adjustParity(k3, 0);
+ ctx.k3 = (DES.Context) des.makeKey(k3, bs);
+ }
+ }
return ctx;
}