Padding
*******

A padding scheme is merely a standard method of ensuring that the input to be encrypted is a multiple of the cipher's block size. The padding schemes of GNU Crypto are in package gnu.crypto.pad and include:

  * PKCS #7. PKCS #7 (referred to as ``PKCS7'' in GNU Crypto) pads the input P with the quantity w = b - (|P| \bmod b), where b is the cipher's block size, encoded as w bytes. That is, if the input is 5 bytes shorter than the required length, then the input is padded with the byte equal to 5 five times. This padding scheme supports block sizes of 2 \leq b \leq 256 bytes.

  * Trailing bit complement. The ``TBC'' pad appends the complement of the last bit in the input until the input is the desired length. That is, if the last bit is 1, then the input is padded with 0, and if the last bit is 0, then the input is padded with 1. This padding scheme supports block sizes up to 256 bytes.

The IPad Interface
==================

Figure 3: Padding class diagram

The IPad interface is used seperately from ciphers and modes. The methods defined by padding schemes are:

 -- Function: void init (int BS) throws java.lang.IllegalStateException, java.lang.IllegalArgumentException
     Initializes this padding scheme for the specified block size. This method throws a java.lang.IllegalStateException if this instance has already been initialized but not reset, and will throw a java.lang.IllegalArgumentException if BS is not a supported block size.

 -- Function: void reset ( )
     Resets this instance, which may then be re-initialized later.

 -- Function: byte[] pad (byte[] INPUT, int OFFSET, int LENGTH)
     Examines the bytes in INPUT as the plaintext, starting at OFFSET and considering LENGTH bytes, and returns the appropriate, possibly empty, byte array containing the padding.

 -- Function: int unpad (byte[] INPUT, int OFFSET, int LENGTH) throws WrongPaddingException
     Examines the bytes in INPUT as the plaintext, starting at OFFSET and considering LENGTH bytes, and returns the number of bytes that should be trimmed off the end of INPUT to unpad the plaintext. Throws a WrongPaddingException if the padding bytes to not correspond to the bytes expected by this padding scheme.

 -- Function: java.lang.String name ( )
     Returns the canonical name of this instance.

 -- Function: boolean selfTest ( )
     Performs a simple conformance test on the padding scheme, to avoid implementation or run time errors.

The PadFactory Class
====================

Padding instances are created with the following method in the PadFactory class:

 -- Function: static IPad getInstance (String PAD)
     Gets an instance of the padding scheme with name PAD, or null if no such padding scheme is available.

This class also defines this method:

 -- Function: static java.util.Set getNames ()
     Returns a set of strings with the names of all padding schemes implemented by GNU Crypto.

Example
=======

The following example pads an input buffer, transforms the padded buffer with already-initialized IMode instances, then unpads the output buffer.

     IPad padding = PadFactory.getInstance("PKCS7");
     padding.init(blockSize);
     byte[] pad = padding.pad(input, 0, input.length);
     byte[] pt = new byte[input.length + pad.length];
     byte[] ct = new byte[pt.length];
     byte[] cpt = new byte[pt.length];
     System.arraycopy(input, 0, pt, 0, input.length);
     System.arraycopy(pad, 0, pt, input.length, pad.length);

     for (int i = 0; i + blockSize < pt.length; i += blockSize)
        {
           enc.update(pt, i, ct, i);
        }

     for (int i = 0; i + blockSize < ct.length; i += blockSize)
        {
           dec.update(ct, i, cpt, i);
        }

     int unpad = padding.unpad(cpt, 0, cpt.length);
     byte[] output = new byte[cpt.length - unpad];
     System.arraycopy(cpt, 0, output, 0, output.length);