All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.security.ext.chaos.ChaosCipherSpi Maven / Gradle / Ivy

Go to download

Artifact for providing java.security infrastructure for the chaos symmetric encryption.

The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////

package org.refcodes.security.ext.chaos;

import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;

import org.refcodes.security.DecryptionException;
import org.refcodes.security.DecryptionException.DecryptionRuntimeException;
import org.refcodes.security.EncryptionException;
import org.refcodes.security.EncryptionException.EncryptionRuntimeException;
import org.refcodes.security.alt.chaos.ChaosDecrypter;
import org.refcodes.security.alt.chaos.ChaosEncrypter;
import org.refcodes.security.alt.chaos.ChaosKey;

/**
 * Thanks Christian Pontesegger for the very good example on "Writing your own
 * JCA extensions - a full cipher" at:
 * "http://codeandme.blogspot.de/2013/07/writing-your-own-jca-extensions-full.html"
 * and for the very good example on "Writing your own JCA extensions - a simple
 * digest " at:
 * "http://codeandme.blogspot.de/2013/06/writing-your-own-jca-extensions-simple.html"
 */
public class ChaosCipherSpi extends CipherSpi {

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private ChaosDecrypter _chaosDecrypter = null;
	private ChaosEncrypter _chaosEncrypter = null;
	private int _mode;

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected byte[] engineDoFinal( byte[] aInput, int aInputOffset, int aInputLength ) throws IllegalBlockSizeException, BadPaddingException {
		return engineUpdate( aInput, aInputOffset, aInputLength );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected int engineDoFinal( byte[] aInput, int aInputOffset, int aInputLength, byte[] output, int outputOffset ) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
		return engineUpdate( aInput, aInputOffset, aInputLength, output, outputOffset );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected int engineGetBlockSize() {
		return 1;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected byte[] engineGetIV() {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected int engineGetOutputSize( int aInputLength ) {
		return 0;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected AlgorithmParameters engineGetParameters() {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void engineInit( int aMode, Key aKey, SecureRandom aRandom ) throws InvalidKeyException {
		_mode = aMode;
		if ( aKey instanceof ChaosKey ) {
			_chaosDecrypter = new ChaosDecrypter( (ChaosKey) aKey );
			_chaosEncrypter = new ChaosEncrypter( (ChaosKey) aKey );
		}
		else {
			throw new InvalidKeyException( "The chaos cipher requires a " + ChaosKey.PROVIDER_NAME + " (chaos) key!" );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void engineInit( int opmode, Key key, AlgorithmParameterSpec aParams, SecureRandom aRandom ) throws InvalidKeyException, InvalidAlgorithmParameterException {
		engineInit( opmode, key, aRandom );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void engineInit( int opmode, Key key, AlgorithmParameters aParams, SecureRandom aRandom ) throws InvalidKeyException, InvalidAlgorithmParameterException {
		engineInit( opmode, key, aRandom );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void engineSetMode( String aMode ) throws NoSuchAlgorithmException {
		throw new NoSuchAlgorithmException();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void engineSetPadding( String aPading ) throws NoSuchPaddingException {
		throw new NoSuchPaddingException();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected byte[] engineUpdate( byte[] aInput, int aInputOffset, int aInputLength ) {
		final byte[] output = new byte[aInputLength];
		try {
			engineUpdate( aInput, aInputOffset, aInputLength, output, 0 );
		}
		catch ( ShortBufferException e ) {
			// output buffer is always big enough
		}

		return output;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected int engineUpdate( byte[] aInput, int aInputOffset, int aInputLength, byte[] aOutput, int aOutputOffset ) throws ShortBufferException {
		if ( aOutput.length - aOutputOffset < aInputLength ) {
			throw new ShortBufferException( "Buffer too short to hold encrypted data!" );
		}

		if ( _mode == Cipher.ENCRYPT_MODE ) {
			try {
				_chaosEncrypter.toEncrypted( aInput, aInputOffset, aInputLength, aOutput, aOutputOffset );
			}
			catch ( EncryptionException e ) {
				throw new EncryptionRuntimeException( e );
			}
			catch ( ArrayIndexOutOfBoundsException e ) {
				throw new ShortBufferException( e.getMessage() );
			}
		}
		else if ( _mode == Cipher.DECRYPT_MODE ) {
			try {
				_chaosDecrypter.toDecrypted( aInput, aInputOffset, aInputLength, aOutput, aOutputOffset );
			}
			catch ( DecryptionException e ) {
				throw new DecryptionRuntimeException( e );
			}
			catch ( ArrayIndexOutOfBoundsException e ) {
				throw new ShortBufferException( e.getMessage() );
			}
		}
		else {
			throw new IllegalStateException( "The aMode of operation is <" + _mode + "> which does neither reflect Cipher.ENCRYPT_MODE <" + Cipher.ENCRYPT_MODE + "> nor Cipher.DECRYPT_MODE <" + Cipher.DECRYPT_MODE + ">!" );
		}

		return aInputLength;
	}

	// /////////////////////////////////////////////////////////////////////////
	// HOOKS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected int engineGetKeySize( Key key ) throws InvalidKeyException {
		if ( key instanceof ChaosCipherSpi ) {
			return 1;
		}
		throw new InvalidKeyException( "The chaos cipher requires a " + ChaosKey.PROVIDER_NAME + " (chaos) key!" );
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy