tribble.crypto
Class BlockCipherSpi

java.lang.Object
  extended byjavax.crypto.CipherSpi
      extended bytribble.crypto.CipherSpi
          extended bytribble.crypto.BlockCipherSpi
Direct Known Subclasses:
NullCipherSpi

public class BlockCipherSpi
extends CipherSpi

Block cipher service provider interface (SPI) implementation.

This class provides the foundation for cipher (encryption) classes that operate on fixed-length blocks. A block cipher encrypts or decrypts blocks of data, one block at a time. A "block" of input is a fixed number of bits wide, and is usually 64 to 256 bits (8 to 32 bytes) in size.

At each stage in the block ciphering process, the output of the cipher may be combined with other blocks within the cipher, depending on the operating mode of the cipher.

The following block encryption modes are supported:

The final block input to the cipher may be padded so that it is same width as the underlying block size. This entails appending extra bytes to the end of the final (partial) data block, which depends on the padding scheme used by the cipher.

The following padding schemes are supported:

Note that none of these methods are synchronized.

Since:
2005-07-11
Version:
API 2, $Revision: 1.2 $ $Date: 2005/09/11 04:06:01 $
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 Also:
StreamCipherSpi, AbstractCipher

Field Summary
static int SERIES
          Class series version.
 
Fields inherited from class tribble.crypto.CipherSpi
DECRYPT_MODE, ENCRYPT_MODE, MODE_BC, MODE_CBC, MODE_CFB, MODE_CFB8, MODE_CTR, MODE_CTR8, MODE_ECB, MODE_OFB, MODE_OFB8, MODE_PBC, MODE_PCBC, MODE_PFB, MODE_PFB8, PADDING_CTS, PADDING_NONE, PADDING_PKCS5, PADDING_ZEROS
 
Constructor Summary
protected BlockCipherSpi(AbstractCipher ciph, java.lang.String mode, java.lang.String pad)
          Constructor.
 
Method Summary
protected  void engineClear()
          Clear (wipe) this cipher.
protected  int engineDoFinal(byte[] in, int inOff, int len, byte[] out, int outOff)
          Add final input bytes to this cipher.
protected  int engineGetKeySize(java.security.Key key)
          Determine the size of a key for this cipher.
protected  int engineGetOutputSize(int n)
          Determine the output buffer size of this cipher.
protected  java.security.AlgorithmParameters engineGetParameters()
          Retrieve algorithm-specific initialization parameters for this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.spec.AlgorithmParameterSpec parms, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.AlgorithmParameters parms, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineSetMode(java.lang.String mode)
          Set the operating mode of this cipher.
protected  void engineSetPadding(java.lang.String padding)
          Set the padding scheme of this cipher.
protected  java.security.Key engineUnwrap(byte[] wrappedKey, java.lang.String alg, int type)
          Unwrap a cipher key from a raw encoded form.
protected  int engineUpdate(byte[] in, int inOff, int len, byte[] out, int outOff)
          Encrypt/decrypt an array of bytes using this cipher.
protected  byte[] engineWrap(java.security.Key key)
          Wrap a cipher key into a raw encoded form.
 
Methods inherited from class tribble.crypto.CipherSpi
engineDoFinal, engineGetBlockSize, engineGetIV, engineGetKeySize, engineSetIV, engineUpdate, finalize
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SERIES

public static final int SERIES
Class series version.

See Also:
Constant Field Values
Constructor Detail

BlockCipherSpi

protected BlockCipherSpi(AbstractCipher ciph,
                         java.lang.String mode,
                         java.lang.String pad)
                  throws java.security.NoSuchAlgorithmException,
                         javax.crypto.NoSuchPaddingException
Constructor.

Parameters:
mode - Operating mode, which must match one of the MODE_XXX constants.
pad - Padding scheme, which must match one of the PADDING_XXX constants}.
Throws:
java.security.NoSuchAlgorithmException - Thrown if mode does not specify a supported operating mode.
javax.crypto.NoSuchPaddingException - Thrown if pad does not specify a supported padding scheme.
Since:
1.1, 2005-09-09
Method Detail

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException
Initialize this cipher.

This method invokes the initialize() method of the underlying cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Symmetric (secret) key for this cipher to use.
rand - Source of random values, or null if they are to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key for use with this cipher.
java.lang.IllegalArgumentException - (unchecked) Thrown if mode is not a valid value.
Since:
1.1, 2005-07-11
See Also:
engineGetParameters(), engineGetIV(), engineSetIV()

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.spec.AlgorithmParameterSpec parms,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException,
                          java.security.InvalidAlgorithmParameterException
Initialize this cipher.

This method invokes the initialize() method of the underlying cipher.

Note that if this cipher is being initialized for decryption, it must be provided with the same algorithm parameters that were used to initialize the cipher that originally encrypted the data that will be fed into this cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Key for this cipher to use.
parms - Algorithm-specific initialization parameters (e.g., an IV passed as a javax.crypto.spec.IvParameterSpec object). If this parameter is null and mode is ENCRYPT_MODE, the IV is initialized from the random source rand; otherwise if mode is DECRYPT_MODE, the IV is initialized to all zeros.
rand - Source of random values, or null if this is to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key (e.g., a javax.crypto.spec.SecretKeySpec) for use with this cipher.
java.security.InvalidAlgorithmParameterException - Thrown if parms is not a proper initialization parameter for this cipher.
java.lang.IllegalArgumentException - (unchecked) Thrown if mode is not a valid value.
Since:
1.1, 2005-09-09
See Also:
engineGetParameters(), engineGetIV(), engineSetIV()

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.AlgorithmParameters parms,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException,
                          java.security.InvalidAlgorithmParameterException
Initialize this cipher.

This method invokes the initialize() method of the underlying cipher.

Note that if this cipher is being initialized for decryption, it must be provided with the same algorithm parameters that were used to initialize the cipher that originally encrypted the data that will be fed into this cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Key for this cipher to use.
parms - Algorithm-specific initialization parameters (e.g., an IV passed as a javax.crypto.spec.IvParameterSpec object).
rand - Source of random values, or null if this is to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key for use with this cipher.
java.security.InvalidAlgorithmParameterException - Thrown if parms is not a proper initialization parameter for this cipher.
Since:
1.1, 2005-07-11
See Also:
engineGetParameters(), engineGetIV(), engineSetIV()

engineSetMode

protected void engineSetMode(java.lang.String mode)
                      throws java.security.NoSuchAlgorithmException
Set the operating mode of this cipher.

Specified by:
engineSetMode in class CipherSpi
Parameters:
mode - Cipher operating mode to use (e.g., "ECB", "CBC", "CFB", "OFB", "PCBC", "BC", etc.). The default mode is "ECB". See the MODE_XXX constants.
Throws:
java.security.NoSuchAlgorithmException - Thrown if mode does not specify a operating mode supported by this cipher.
java.lang.NullPointerException - (unchecked) Thrown if mode is null.
Since:
1.1, 2005-07-11

engineSetPadding

protected void engineSetPadding(java.lang.String padding)
                         throws javax.crypto.NoSuchPaddingException
Set the padding scheme of this cipher.

Specified by:
engineSetPadding in class CipherSpi
Parameters:
padding - Cipher padding scheme to use (e.g., "PKCS5Padding"). The default scheme is "NoPadding". See the PADDING_XXX constants.
Throws:
javax.crypto.NoSuchPaddingException - Thrown if padding does not specify a padding scheme supported by this cipher.
java.lang.NullPointerException - (unchecked) Thrown if padding is null.
Since:
1.1, 2005-07-11

engineGetKeySize

protected int engineGetKeySize(java.security.Key key)
                        throws java.security.InvalidKeyException
Determine the size of a key for this cipher.

Overrides:
engineGetKeySize in class CipherSpi
Parameters:
key - A key suitable for use with this cipher.
Returns:
Key size (in bits) of the given key.
Throws:
java.security.InvalidKeyException - Thrown if the given key cannot be used with this cipher.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this method is not overridden.
java.lang.NullPointerException - (unchecked) Thrown if key is null.
Since:
1.1, 2005-09-09

engineGetOutputSize

protected int engineGetOutputSize(int n)
Determine the output buffer size of this cipher.

Specified by:
engineGetOutputSize in class CipherSpi
Parameters:
n - Size of the input buffer (in addition to any previous pending input bytes).
Returns:
Output buffer size (in bytes) that will be created by this cipher.
Throws:
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-07-11

engineGetParameters

protected java.security.AlgorithmParameters engineGetParameters()
Retrieve algorithm-specific initialization parameters for this cipher.

Specified by:
engineGetParameters in class CipherSpi
Returns:
Algorithm-specific initialization parameters (e.g., an IV value as a javax.crypto.spec.IvParameterSpec object).
Throws:
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-09-09

engineUpdate

protected int engineUpdate(byte[] in,
                           int inOff,
                           int len,
                           byte[] out,
                           int outOff)
                    throws javax.crypto.ShortBufferException
Encrypt/decrypt an array of bytes using this cipher.

This method handles blocking and padding of the input data, operating modes, and so forth required of symmetric block ciphers.

Encryption

 Input:
          |- - - - - - - - - input length  - - - - - - - - - -|
          :                                                   :
          :             plaintext input blocks                :
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    |pend :XXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXX:     |
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    :     :                                             :     :
    :     :                                             :     :
    |- - -| previous pending input length               :     :
    :                                                   :     :
    |- - - - - - - - - total input length  - - - - - - - - - -|
    :                                                   :     :
    |- - - - - - - complete input blocks - - - - - - - -|     :
                                                        :     :
                          leftover pending input length |- - -|

 Output:
                       ciphertext output blocks
    +===========+=========+=========+===/ /===+=========+= = =:= = =+
    |XXXXXXXXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|pend :     |
    +===========+=========+=========+===/ /===+=========+= = =:= = =+
    :                                                   :     :
    :                                                   :     :
    |- - - - - - - - - - output length  - - - - - - - - |     :
                                                        :     :
                               new pending input length |- - -| 

Note that only complete input blocks are encrypted, resulting in the cumulative output length being a multiple of the cipher block size. Leftover partial blocks are saved and prepended to the next group of input bytes to be encrypted.

Decryption

 Input:
          |- - - - - - - - - input length  - - - - - - - - - -|
          :                                                   :
          :             ciphertext input blocks               :
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    |pend :XXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXX:     |
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    :     :                                             :     :
    :     :                                             :     :
    |- - -| previous pending input length               :     :
    :                                                   :     :
    |- - - - - - - - complete input blocks - - - - - - -|     :
                                                        :     :
                          leftover pending input length |- - -|

 Output:
                        plaintext output blocks
    +===========+=========+=========+===/ /===+=========+=====:= = =+
    |XXXXXXXXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXX:     |
    +===========+=========+=========+===/ /===+=========+=====:= = =+
    :                                                   :     :
    :                                                   :     :
    |- - - - - - - - - - output length  - - - - - - - - |     :
                                                        :     :
                       new pending partial output block |- - -| 

Note that only complete input blocks are decrypted, resulting in the cumulative output length being a multiple of the cipher block size. Leftover partial blocks are saved and prepended to the next group of input bytes to be decrypted.

Specified by:
engineUpdate in class CipherSpi
Parameters:
in - Array of bytes to encrypt/decrypt. The data from this array is appended to any input data previously added to this cipher.
inOff - Index of the first byte in array in to encrypt/decrypt.
len - Number of bytes in array in to encrypt/decrypt.
out - Resulting encrypted/decrypted output bytes.
outOff - Index of the first byte in array out to write the resulting output bytes to.
Returns:
Number of encrypted/decrypted bytes written into array out. Only complete encrypted/decrypted blocks are written to the output array. Partially complete blocks are not written, and are kept pending within this cipher object.
Throws:
javax.crypto.ShortBufferException - Thrown if the output buffer is too small to hold the resulting data.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
java.lang.IllegalArgumentException - (unchecked) Thrown if len is negative.
Since:
1.1, 2005-09-09

engineDoFinal

protected int engineDoFinal(byte[] in,
                            int inOff,
                            int len,
                            byte[] out,
                            int outOff)
                     throws javax.crypto.ShortBufferException
Add final input bytes to this cipher. The added bytes are encrypted/decrypted, being appended to any input bytes that were previously added to this cipher.

Encryption

 Input:
          |- - - - - - - - final input length  - - - - - - - -|
          :                                                   :
    |- - -| previous pending input length                     :
    :     :                                                   :
    :     :             plaintext input blocks                :
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    |pend :XXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXX: pad |
    += = =:=====+=========+=========+===/ /===+=========+=====:= = =+
    :                                                         :     :
    :                                                         :     :
    :                                     final block padding |- - -|
    :                                                               :
    |- - - - - - - - - - complete input blocks - - - - - - - - - - -|

 Output:
                       ciphertext output blocks
    +===========+=========+=========+===/ /===+=========+===========+
    |XXXXXXXXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXXXXXXXX|
    +===========+=========+=========+===/ /===+=========+===========+
    :                                                               :
    :                                                               :
    |- - - - - - - - - - final output length - - - - - - - - - - - -|

Note that the final output length results in the total number of output bytes being a multiple of the cipher block size.

Decryption

 Input:
          |- - - - - - - - - - final input length  - - - - - - - - -|
          :                                                         :
          :               ciphertext input blocks                   :
    += = =:=====+=========+=========+===/ /===+=========+===========+
    |pend :XXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXXXXXXXX|
    += = =:=====+=========+=========+===/ /===+=========+===========+
    :     :                                                         :
    :     :                                                         :
    |- - -| previous pending input length                           :
    :                                                               :
    |- - - - - - - - - - - complete input blocks - - - - - - - - - -|

 Output:
                        plaintext output blocks
    +===========+=========+=========+===/ /===+=========+=====:= = =+
    |XXXXXXXXXXX|XXXXXXXXX|XXXXXXXXX|  . . .  |XXXXXXXXX|XXXXX: pad |
    +===========+=========+=========+===/ /===+=========+=====:= = =+
    :                                                         :     :
    :                                                         :     :
    :                                       truncated padding |- - -|
    :                                                         :
    |- - - - - - - - - final output length - - - - - - - - - -| 

Note that the final input length must result in the total number of input bytes being a multiple of the cipher block size.

Specified by:
engineDoFinal in class CipherSpi
Parameters:
in - Array of bytes to add as input to this cipher.
inOff - Index of the first byte in array in to input to this cipher.
len - Number of bytes in array in to input to this cipher.
out - Output array to write the resulting encrypted/decrypted bytes to.
outOff - Index of the first byte in array out to write the resulting output bytes to.
Returns:
Number of output bytes produced by this cipher.
Throws:
javax.crypto.BadPaddingException - Thrown if the final input block does not contain the appropriate padding (decrypt mode only).
javax.crypto.IllegalBlockSizeException - Thrown if the total number of input bytes so far is insufficient to produce a complete output block (encrypt mode only).
javax.crypto.ShortBufferException - Thrown if the output buffer is too small to hold the resulting data.
java.lang.IllegalArgumentException - (unchecked) Thrown if len is negative.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-09-09

engineWrap

protected byte[] engineWrap(java.security.Key key)
                     throws javax.crypto.IllegalBlockSizeException,
                            java.security.InvalidKeyException
Wrap a cipher key into a raw encoded form.

Overrides:
engineWrap in class CipherSpi
Parameters:
key - Key suitable for use with this cipher.
Returns:
The key in a raw encoded format.
Throws:
javax.crypto.IllegalBlockSizeException - Thrown if key is not encoded with a block length supported by this cipher.
java.security.InvalidKeyException - Thrown if key is not a valid key for this cipher.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this operation is not supported by this cipher.
Since:
1.1, 2005-09-09
See Also:
engineUnwrap()

engineUnwrap

protected java.security.Key engineUnwrap(byte[] wrappedKey,
                                         java.lang.String alg,
                                         int type)
                                  throws java.security.InvalidKeyException,
                                         java.security.NoSuchAlgorithmException
Unwrap a cipher key from a raw encoded form.

Overrides:
engineUnwrap in class CipherSpi
Returns:
The key, decoded into a form suitable for use with this cipher.
Throws:
java.security.InvalidKeyException - Thrown if key is not a valid key for this cipher.
java.security.NoSuchAlgorithmException - Thrown if key is not encoded in a recognizable form.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this operation is not supported by this cipher.
Since:
1.1, 2005-09-09
See Also:
engineWrap()

engineClear

protected void engineClear()
Clear (wipe) this cipher. Erases all sensitive information contained within this object.

This method invokes the clear() method of the underlying cipher.

This method is not part of the standard set defined in class javax.crypto.CipherSpi, but is provided as a convenient enhancement.

Note that this cipher object is no longer usable after calling this method.

Overrides:
engineClear in class CipherSpi
Since:
1.1, 2005-07-05