diff options
author | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-07-21 23:10:27 +0000 |
---|---|---|
committer | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-07-21 23:10:27 +0000 |
commit | 33e51584f976c04344b1cff1536694140d31ea55 (patch) | |
tree | acda1d1d7ee70145525d70423b28e2ba0ab16e64 /gnu | |
parent | ed4ca6d45cc58fbb859b8a86ce4241d2bfdadedc (diff) | |
download | classpath-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.java | 132 |
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; } |