@node Modes, Padding, Ciphers, Top
@chapter Modes

@menu
* The IMode Interface::             The standard mode interface.
* The ModeFactory Class::           How to obtain a mode instance.
* Mode Example::                    A simple programming example.
@end menu

@cindex modes
@cindex @code{gnu.crypto.mode} package

Cipher modes operate on the next level up from the underlying block
cipher. They transform the blocks going in and out of the cipher in ways
to give them desirable properties in certain circumstances. The cipher
modes implemented by GNU Crypto, which is contained in the
@code{gnu.crypto.mode} package and are referenced herein by their
three-letter abbreviations described below, are:

@itemize @bullet

@cindex CBC, cipher block chaining mode

@c The texi2html + latex2html combination seems to be broken
@c beyond repair, so we'll do some fudging with the math here.
@c
@c Yes, we could possibly just allow this to come out ugly in certain
@c situations, but I'm a typography nerd and will refuse to do so.

@item
@b{Cipher block chaining mode}. The ``CBC'' mode makes every block of
the ciphertext depend upon all previous blocks by adding @i{feedback} to
the transformation. This is done by XORing the plaintext with the
previous ciphertext (or, with the first block, an initialization vector)
before it is transformed. That is, encryption looks like:
@tex
$C_i = E_k(P_i \oplus C_{i-1})$; and decryption is
@end tex
@ifnottex
C[i] = ENCRYPT(k, P_i ^ C[i-1]); and decryption is
@end ifnottex
@tex
$P_i = C_{i-1} \oplus E_k^{-1}(C_i)$.
@end tex
@ifnottex
P[i] = C[i-1] ^ DECRYPT(C[i]).
@end ifnottex

@cindex CTR, counter mode

@item
@b{Counter mode}. Counter mode, referred to as ``CTR'' mode, is one of a
class of sequenced cipher modes that turn the underlying cipher into a
@i{keystream}. Counter mode relys on a simple counter register that is
updated for every block processed. For plaintexts
@tex
  $P_1\dots P_n$,
@end tex
@ifnottex
  P[1] ... P[n],
@end ifnottex
ciphertexts
@tex
  $C_1\dots C_n$,
@end tex
@ifnottex
  C[1] ... C[n],
@end ifnottex
counter elements
@tex
  $T_1\dots T_n$,
@end tex
@ifnottex
  T[1] ... T[n],
@end ifnottex
and an encryption function
@tex
  $E_k$,
@end tex
@ifnottex
  ENCRYPT(k, ...),
@end ifnottex
encryption is defined as
@tex
  $C_i = P_i \oplus E_k(T_i)$
@end tex
@ifnottex
  C[i] = P[i] ^ ENCRYPT(k, T[i])
@end ifnottex
and decryption as
@tex
  $P_i = C_i \oplus E_k(T_i)$.
@end tex
@ifnottex
  P[i] = C[i] ^ ENCRYPT(k, T[i]).
@end ifnottex

@cindex ECB, electronic codebook mode

@item
@b{Electronic codebook mode}. Or ``ECB'' mode, is the most obvious
cipher mode: the cipher block is the direct output of the forward
function, and the plain block is the direct output of the inverse
function. That is, encryption is @math{C_i = E_k(P_i)} and decryption is
@math{P_i = E_k^\bgroup-1\egroup(C_i)}.

@cindex ICM, integer counter mode

@item
@b{Integer counter mode}. ``ICM'' mode has features in common with
counter mode described above. The counter, @math{T_i}, is computed by
@math{T_i = (T_0 + i) \bmod 256^b}, where @math{b} is the cipher's
block size. @math{T_0} is initialized to the integer representation of
some initialization vector. The keystream bytes are then
@math{E_k(T_i)}. Encryption and decryption are then
@math{C_i = P_i \oplus E_k(T_i)} and
@math{P_i = C_i \oplus E_k(T_i)}, respectively.

@cindex OFB, output feedback mode

@item
@b{Output feeback mode}. ``OFB'' mode creates a keystream by repeatedly
iterating the underlying block cipher over an initialization vector.
That is, the @math{i}th keystream block is @math{X_i = E(X_\bgroup i-1\egroup)}
for @math{1 < i \leq n}, and @math{X_1 = IV}. Like the other stream modes, the
input block @math{i} is transformed by the exclusive-or of the block
with @math{X_i}.

@end itemize

@node The IMode Interface, The ModeFactory Class, , Modes
@section The IMode Interface

@cindex @code{IMode} interface

The @code{IMode} interface is similar to the @code{IBlockCipher}
interface, except modes have a @i{state} associated with them, e.g.
whether the instance is used for encryption or decryption. The
@code{IMode} interface is usually the one that is used when encrypting
or decrypting; @code{IBlockCipher} is used when the lowest level---the
cipher function itself---needs to be accessed. @code{IMode} extends
@code{IBlockCipher} interface, and thus all methods specified in that
interface are implemented in modes, and have the same meaning. The
properties passed to the @code{init} method of @code{IBlockCipher} may
also be passed to the @code{init} mehtod of @code{IMode}, along with the
following property names.

@cindex @b{STATE} variable (@code{IMode})

@fgindex Modes class diagram
@iftex
   @image{diagrams/mode_class_diag, 326pt, 202pt}
   @center @i{Figure 2: Modes class diagram}
@end iftex
@ifnottex
   @image{diagrams/mode_class_diag}
   @center @i{Figure 2: Modes class diagram}
@end ifnottex

@deftypevar java.lang.String STATE
The property name for the mode's state, as passed to the @code{init}
method. Values for this property are an @code{java.lang.Integer}
containing either the @code{ENCRYPTION} constant or the
@code{DECRYPTION} constant.
@end deftypevar

@cindex @b{ENCRYPTION} variable (@code{IMode})

@deftypevar int ENCRYPTION
The value passed for the @code{STATE} property, wrapped in a
@code{java.lang.Integer}, which indicates that the instance is to be
used for encryption.
@end deftypevar

@cindex @b{DECRYPTION} variable (@code{IMode})

@deftypevar int DECRYPTION
The value passed for the @code{STATE} property, wrapped in a
@code{java.lang.Integer}, which indicates that the instance is to be
used for decryption.
@end deftypevar

@cindex @b{MODE_BLOCK_SIZE} variable (@code{IMode})

@deftypevar java.lang.String MODE_BLOCK_SIZE
The property name for the block size of this mode. The value for this
propery should be a @code{java.lang.Integer} of the block size. If
omitted, the underlying cipher's block size is used.
@end deftypevar

@cindex @b{IV} variable (@code{IMode})

@deftypevar java.lang.String IV
The property name for the initialization vector to initialize this mode
with, if required. The value should be a byte array equal in size to the
@code{MODE_BLOCK_SIZE} property. If omitted a byte array consisting of
zeros is used.
@end deftypevar

@cindex @b{update} function (@code{IMode})

@deftypefun void update (byte[] @var{in}, int @var{inOffset}, byte[] @var{out}, int @var{outOffset}) throws java.lang.IllegalStateException
Transforms the block in @var{in} starting at @var{inOffset} into the
block in @var{out} starting at @var{outOffset}. Encryption or decryption
is performed depending upon the value passed along with the @code{state}
property given to the @code{init} method. A
@code{java.lang.IllegalStateException} is thrown if this instance has
not been initialized, and it is up to the programmer to ensure that
there is one full block in @var{in} starting at @var{inOffset}, and
enough space for one full block in @var{out} starting at
@var{outOffset}. Since modes can have states, and may require that the
be used in a particular sequence, using this method is preferred over
the @code{encryptBlock} and @code{decryptBlock} methods of
@code{IBlockCipher}.
@end deftypefun

@node The ModeFactory Class, Mode Example, The IMode Interface, Modes
@section The ModeFactory Class

@cindex @code{ModeFactory} class

The preferred way to get mode instances is through the
@code{ModeFactory} class, from one of the following methods:

@cindex @b{getInstance} function (@code{ModeFactory})

@deftypefun {static IMode} getInstance (java.lang.String @var{mode}, java.lang.String @var{cipher}, int @var{cipherBlockSize})
Returns an instance of @var{cipher} wrapped in an instance of
@var{mode}, initialized to a block size of @var{cipherBlockSize}, or
returns @code{null} if no appropriate cipher or mode is available. The
@var{mode} argument is one of the names described above, and
@var{cipher} is one of the names described in the Ciphers chapter.
@end deftypefun

@deftypefun {static IMode} getInstance (java.lang.String @var{mode}, IBlockCipher @var{cipher}, int @var{cipherBlockSize})
Returns an instance of @var{mode} using the already-initialized
@var{cipher}, initializing the mode with a block size of
@var{cipherBlockSize}, or returns @code{null} if no appropriate mode is
available.
@end deftypefun

Additionally the following method is defined:

@cindex @b{getNames} function (@code{ModeFactory})

@deftypefun {static java.util.Set} getNames ()
This method returns a @code{java.util.Set} of the names (each element of
type @code{java.lang.String}) of all supported modes.
@end deftypefun

@node Mode Example
@section Example

@cindex example, modes

The following example encrypts and decrypts a byte array with the AES in
CFB mode. See the next chapter on padding for instances where the input
is not a multiple of the cipher or mode's block size.

@example
IMode mode = ModeFactory.getInstance("CFB", "AES", 16);
Map attributes = new HashMap();

// These attributes are defined in gnu.crypto.cipher.IBlockCipher.
attributes.put(IMode.KEY_MATERIAL, key_bytes);
attributes.put(IMode.CIPHER_BLOCK_SIZE, new Integer(16));

// These attributes are defined in IMode.
attributes.put(IMode.STATE, new Integer(IMode.ENCRYPTION));
attributes.put(IMode.IV, iv_bytes);
mode.init(attributes);
int bs = mode.currentBlockSize();

for (int i = 0; i + bs < pt.length; i += bs)
   @{
      mode.update(pt, i, ct, i);
   @}

mode.reset();
attributes.put(IMode.STATE, new Integer(IMode.DECRYPTION);
mode.init(attributes);

for (int i = 0; i + bs < ct.length; i += bs)
   @{
      mode.update(ct, i, cpt, i);
   @}
@end example
