org.refcodes.security.ext.chaos.ChaosCipherSpi Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-security-ext-chaos Show documentation
Show all versions of refcodes-security-ext-chaos Show documentation
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!" );
}
}