//============================================================================== // SymmetricCipher.java //============================================================================== package tribble.crypto; // System imports import java.lang.Exception; import java.lang.String; import java.lang.System; import java.security.InvalidKeyException; import java.security.Key; // Local imports import tribble.util.HexDump; /******************************************************************************* * Abstract base class for primitive symmetric cipher (encryption) algorithms. * Symmetric ciphers use the same secret key for both encryption and decryption * (hence the term symmetric). * *

* Classes that extend this base class implement fundamental symmetric block * ciphers, which comprise the foundation upon which this package package is * built. * * * @version $Revision: 1.2 $ $Date: 2005/07/09 14:41:20 $ * @since 2005-07-05 * @author * David R. Tribble * (david@tribble.com). * *

* Copyright ©2005 by David R. Tribble, all rights reserved. *
* Permission is granted to freely use and distribute this source code * provided that the original copyright and authorship notices remain * intact. * * @see AsymmetricCipher * @see CipherSpi */ public abstract class SymmetricCipher extends tribble.crypto.AbstractCipher { // Identification /** Revision information. */ static final String REV = "@(#)tribble/crypto/SymmetricCipher.java $Revision: 1.2 $ $Date: 2005/07/09 14:41:20 $\n"; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Private constants //---------------------------------- // Test vectors (see {@link #main}) private static final byte[] TEST_KEY = { (byte) 0x44, (byte) 0x61, (byte) 0x76, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x52, (byte) 0x2E, (byte) 0x20, (byte) 0x54, (byte) 0x72, (byte) 0x69, (byte) 0x62, (byte) 0x62, (byte) 0x6C, (byte) 0x65, }; private static final byte[] TEST_PLAINTEXT = { (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x00, (byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xA5, (byte) 0xC3, (byte) 0xB4, (byte) 0x81, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected static methods /*************************************************************************** * Test driver. * This convenience method is used by classes that extend this base class. * *

* Usage * * java tribble.crypto.SomeCipher [args...] * * * * @param ciph * Derived class cipher object to test. * * @param key * Symmetric key for the cipher. * * @param input * Input test vector. * This array should be exactly the same length as the cipher block size. * * @throws Exception * Thrown if an error occurs in the encryption engine. * * @since 1.1, 2005-07-05 */ protected static void test(SymmetricCipher ciph, String[] args) throws Exception { // Check args if (args.length < 1) { test(ciph, TEST_KEY, TEST_PLAINTEXT); } else { /*+++INCOMPLETE ...; +++*/ } } /*************************************************************************** * Test driver. * This convenience method is used by classes that extend this base class. * *

* Usage * * java tribble.crypto.SomeCipher * * * * @param ciph * Derived class cipher object to test. * * @param key * Symmetric key for the cipher. * * @param input * Input test vector. * This array should be exactly the same length as the cipher block size. * * @throws Exception * Thrown if an error occurs in the encryption engine. * * @since 1.1, 2003-04-05 */ protected static void test(SymmetricCipher ciph, /*const*/ byte[] key, /*const*/ byte[] input) throws Exception { byte[] e; byte[] d; int blen; boolean pass; // Initialize the cipher with an encryption key System.out.println("Initialize the cipher for encryption"); System.out.println("Key:"); HexDump.hexDump(System.out, key); ciph.initialize(key, false); ciph.m_decrypt = false; blen = ciph.m_blockLen; // Encrypt the test vector System.out.println("Input data:"); HexDump.hexDump(System.out, input); if (input.length < blen) throw new Exception("Input block length must be " + blen); e = new byte[ciph.m_blockLen]; ciph.blockEncrypt(input, 0, e, 0); System.out.println("Encrypted data:"); HexDump.hexDump(System.out, e); System.out.println(); // Prepare to decrypt the encrypted test vector System.out.println("Re-Initialize the cipher for decryption"); System.out.println("Key:"); HexDump.hexDump(System.out, key); ciph.initialize(key, true); ciph.m_decrypt = true; blen = ciph.m_blockLen; // Decrypt the encrypted test vector System.out.println("Input data:"); HexDump.hexDump(System.out, e); if (e.length < blen) throw new Exception("Encrypted block length must be " + blen); d = new byte[ciph.m_blockLen]; ciph.blockDecrypt(e, 0, d, 0); System.out.println("Decrypted data:"); HexDump.hexDump(System.out, d); System.out.println(); // Verify the results pass = true; for (int i = 0; i < blen; i++) if (d[i] != input[i]) pass = false; System.out.println((pass ? ">>> PASS" : ">>> FAIL")); System.out.println(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected variables /** Cipher block size (in bytes). */ protected int m_blockLen; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Public methods /*************************************************************************** * Retrieve the block size of this cipher. * * @return * The block size of this cipher algorithm (in bytes). * * @since 1.1, 2005-07-05 */ public int getBlockSize() /*const*/ { return (m_blockLen); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected constructors /*************************************************************************** * Constructor. * * @param alg * Cryptographic cipher algorithm name. * * @param blockLen * Cipher block size (in bytes). * * @since 1.1, 2005-07-05 */ protected SymmetricCipher(String alg, int blockLen) { // Initialize super(alg); m_blockLen = blockLen; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected methods /*************************************************************************** * Encrypt a block of plaintext. * * @param in * Array containing a single block of plaintext bytes to encrypt. * The length of the block is exactly equal to the cipher block size * ({@link #m_blockLen}). * * @param inOff * Index of the first byte of the plaintext block within array in to * encrypt. * * @param out * Array that will be filled with the encrypted ciphertext block. * The length of the block is exactly equal to the cipher block size * ({@link #m_blockLen}). * * @param outOff * Index of the first byte of array out to fill with the encrypted * ciphertext block. * * @see #blockDecrypt blockDecrypt() * * @since 1.1, 2005-07-05 */ protected abstract void blockEncrypt(/*const*/ byte[] in, int inOff, byte[] out, int outOff); /*************************************************************************** * Decrypt a block of ciphertext. * * @param in * Array containing a single block of ciphertext bytes to decrypt. * The length of the block is exactly equal to the cipher block size * ({@link #m_blockLen}). * * @param inOff * Index of the first byte of the ciphertext block within array in * to decrypt. * * @param out * Array that will be filled with the decrypted plaintext block. * The length of the block is exactly equal to the cipher block size * ({@link #m_blockLen}). * * @param outOff * Index of the first byte of array out to fill with the decrypted * plaintext block. * * @see #blockEncrypt blockEncrypt() * * @since 1.1, 2005-07-05 */ protected abstract void blockDecrypt(/*const*/ byte[] in, int inOff, byte[] out, int outOff); } // End SymmetricCipher.java