For the latest news and information visit The GNU Crypto project

## gnu.crypto.exp.ust
Class UST

    java.lang.Object
      |
      +--gnu.crypto.exp.ust.UST

public class UST
extends java.lang.Object

The Universal Security Transform (UST) is a cryptographic transform for providing confidentiality, message authentication, and replay protection. This transform is sufficient for providing these services to network protocols, though it does not specify a protocol itself.

UST has the following parameters:

- INDEX_LENGTH: The number of octets in an Index.
- MAX_KEYSTREAM_LENGTH: The maximum number of octets in a keystream segment.
- PREFIX_LENGTH: The number of octets in the keystream prefix.
- TAG_LENGTH: The number of octets in an Authentication Tag.
- MAX_HASH_LENGTH: The maximum number of octets that can be input to the hash function.
- HASH_KEY_LENGTH: The number of octets in a hash key.

All of these parameters MUST remain fixed for any given UST context.

The parameters `INDEX_LENGTH` and `MAX_KEYSTREAM_LENGTH` are defined by the keystream generator. This is because the keystream generators used in UST are families of length-expanding pseudorandom functions. At the time of implementing UST, the only such generators available are (a) `UMacGenerator` and (b) `ICMGenerator`. Yet, both of these two algorithms require more than just these two parameters to be fully qualified, and hence instantiated. They both require an underlying block cipher as well as a block size and key material. While default values are used for the former two of these parameters -if they are not included in their initialisation `Map`- the latter parameter; i.e. key material, should be specified.

The parameters `TAG_LENGTH`, `MAX_HASH_LENGTH`, and `HASH_KEY_LENGTH` are defined by the hash function. Please note that when the UST document refers to a hash function it actually means a Universal Hash Function. At the time of implementing UST, the only such functions available are `UHash32` and `TMMH16`, with the latter more suited for UST purposes because it is independent from any other algorithm --the same is not true for (our implementation of) `UHash32` because of its current dependencies on `UMac32`; although this may change in the future. For this reason we shall only allow `TMMH16` as the UST's underlying Universal Hash Function.

The length of any Plaintext protected by UST MUST NOT exceed the smaller of `(MAX_KEYSTREAM_LENGTH - TAG_LENGTH)` and `MAX_HASH_LEN`.

The value of `HASH_KEY_LENGTH` MUST be no greater than `MAX_KEYSTREAM_LENGTH`. The value of `TAG_LENGTH` MUST be no greater than `HASH_KEY_LENGTH`.

Once a UST instance is initialised, one can (a) authenticate designated bytes -an operation that does not yield any output- and/or (b) encipher designated bytes -an operation that does yield an output equal in length to the input.

The understanding of the author of this implementation is that an initialised UST can be used to process different messages while relying on that UST to generate and use a different index value for each message without the need for specifying eveytime that value; i.e. the implementation shall keep track of the index to ensure no previously used value, generated and used with the same key material, is ever re-used. Furthermore, because we want to maximise the possible length of messages processed by a UST with a given key material, each new/updated index value should yield two keystream generators: one for use with the Integrity Protection service (referred to as the Authentication Function in the UST draft), and the other for use to encipher the message (Confidentiality Protection service) --see Figures 1 and 2 in the UST draft. This way the maximum plaintext protected by such a UST is `(MAX_KEYSTREAM_LENGTH - TAG_LENGTH)` only, and the number of different messages protected by one set of key material is `(2^(8*INDEX_LENGTH) - 1)` --the index value `0` being reserved to generate all other keying material! To achieve this objective this implementation does the following:

1. We define `MAX_INDEX` to be `(2^(8*INDEX_LENGTH) - 1)` --all length quantities are expressed in bytes.
2. With every initialisation of a UST, a keying index of value `0` and the user-supplied key material are used to initialise an internal keystream generator. A message index is initialised to `-1`.
3. With every start-of-message, (a) increment the message index, and (b) check if it is greater than `MAX_INDEX`. If it is we throw an exception. Otherwise, we generate from the internal keystream enough key material to initialise two keystream generators, both with that same index, one for the Integrity Protection Function and the other for the Confidentiality Protection Function. Please note that strictly speaking, the first of this pair of keystreams is NOT the Confidentiality Protection Function keystream generator, since it is also used to generate the bytes of the Integrity Protection Function's Prefix. In other words, as soon as we detect the requirement for Integrity Protection service, we instantiate the keystream generator pair, even if the Confidentiality Protection service is not required.
4. If on the other hand, the start-of-message includes a designated index value, we use that index as is, in combination with enough key material generated by our internal keystream.
5. With every process-message (be it autheticate or encipher) we process the message through one or both functions as desired (integrity protection only, or integrity protection as well as confidentiality protection).
6. With every end-of-message, we terminate the integrity protection and compute the authentication tag.
7. It is easy to show that it is possible to re-construct the state of such a UST, given the user-supplied key material and a designated index value.
8. The new constraint that would limit the number of messages, and their length, with this scheme becomes:

           MAX_INDEX * 2 * (BLOCK_SIZE - INDEX_LENGTH) <= MAX_KEYSTREAM_LENGTH

   where `BLOCK_SIZE` is the underlying cipher's block size in bytes.

Another alternative to using two keystream generators, would have been to (a) use only one, but (b) in-line the code of the Authentication Function inside the UST. This way, (a) enough output bytes from that keystream would be used to setup the Authentication Function, and (b) the same output bytes from that keystream would be used to compute the authentication context, as well as encipher the message. But this weakens the UST, since an attacker, with a known plaintext, can reconstruct the keystream generator output (used for both the authentication and encipherement functions) by simply xoring the message with the ciphertext.

The next figure depicts a block diagram of our implementation of the UST:

       +----------------------------+               +-----------+
       | user-supplied key material +------+  +-----+ Index = 0 |
       +----------------------------+      |  |     +-----------+
                                           V  V
       +-----------+          +------------------------------+
       |   Index   |          | Internal Keystream Generator |
       +-----+-----+          +-------------+----------------+
             |                              |
        +----|------------------------------+
        |    |    +-----------------+
        |    +--->| Confidentiality |
        +----|--->|   Protection    +--+-----------------+
        |    |    |    Generator    |  |                 |
        |    |    +-----------------+  V                 V
        |    |                 +------------+---------------------------+
        |    |    +------------+   Prefix   |         Suffix            +---+
        |    |    |            +------------+---------------------------+   |
        |    |    |                 <------------- message ------------->   |
        |    |    |                 +-------+---------------------------+   |
        |    |    |         +-------+ Clear |          Opaque           +--(+)
        |    |    |         |       +-------+---------------------------+   |
        |    |    |         |               +---------------------------+   |
        |    |    |         |      +--------+         Ciphertext        |<--+
        |    |    |         |      |        +---------------------------+
        |    |    |         V      V
        |    |    |    +-----------------+
        |    |    +--->|    Integrity    |    +-----------+
        |    +-------->|   Protection    +--->| Auth. Tag |
        +------------->|    Generator    |    +-----------+
                       +-----------------+

References:

1. The Universal Security Transform, David A. McGrew.

Field Summary
`static java.lang.String` `CIPHER` Property name of the keystream underlying cipher.
`static java.lang.String` `CONFIDENTIALITY` Property name of the confidentiality protection flag.
`static java.lang.String` `INDEX_LENGTH` Property name of a UST index_length.
`static java.lang.String` `INTEGRITY` Property name of the integrity protection flag.
`static java.lang.String` `KEY_MATERIAL` Property name of the UST user-supplied key material.
`static java.lang.String` `KEYSTREAM` Property name of the keystream generator type to use.
`static java.lang.String` `TAG_LENGTH` Property name of the authentication tag length in bytes.

Constructor Summary
`UST()`

Method Summary
`byte[]` `beginMessage()` Signals the start of a new message to process with this `UST`.
`void` `beginMessageWithIndex(java.math.BigInteger ndx)` Signals the start of a new message to process with this `UST` with a designated <emIndex value.
`void` `beginMessageWithIndex(int ndx)` Signals the start of a new message to process with this `UST` with a designated <emIndex value.
`void` `doClear(byte[] in, int offset, int length)` Process the Clear part of the message.
`void` `doOpaque(byte[] in, int inOffset, int length, byte[] out, int outOffset)` Process the Opaque part of the message.
`byte[]` `endMessage()` Signals the end of the message transformation.
`void` `init(java.util.Map attributes)` Initialise this instance with the designated set of attributes.
`void` `reset()` Reset this instance and prepare for processing a new message.
`boolean` `selfTest()`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Field Detail

### INDEX_LENGTH

    public static final java.lang.String INDEX_LENGTH

  Property name of a UST index_length.

  See Also:
    Constant Field Values

### KEYSTREAM

    public static final java.lang.String KEYSTREAM

  Property name of the keystream generator type to use.

  See Also:
    Constant Field Values

### CIPHER

    public static final java.lang.String CIPHER

  Property name of the keystream underlying cipher.

  See Also:
    Constant Field Values

### KEY_MATERIAL

    public static final java.lang.String KEY_MATERIAL

  Property name of the UST user-supplied key material.

  See Also:
    Constant Field Values

### TAG_LENGTH

    public static final java.lang.String TAG_LENGTH

  Property name of the authentication tag length in bytes.

  See Also:
    Constant Field Values

### CONFIDENTIALITY

    public static final java.lang.String CONFIDENTIALITY

  Property name of the confidentiality protection flag.

  See Also:
    Constant Field Values

### INTEGRITY

    public static final java.lang.String INTEGRITY

  Property name of the integrity protection flag.

  See Also:
    Constant Field Values

Constructor Detail

### UST

    public UST()

Method Detail

### init

    public void init(java.util.Map attributes)

  Initialise this instance with the designated set of attributes.

  The possible attributes for a `UST` are:

  - `CONFIDENTIALITY`: a `Boolean` that indicates if Confidentiality Protection service is to be activated for messages processed with this instance.
  - `INTEGRITY`: a `Boolean` that indicates if Integrity Protection service is to be activated for messages processed with this instance.
  - `KEYSTREAM`: a `String` that indicates the algorithm name of the underlying keystream generators used with this instance. Currently the only allowed values are: `Registry.UMAC_PRNG` and `Registry.ICM_PRNG`.
  - `INDEX_LENGTH`: a `Integer` that is only needed if the `Registry.ICM_PRNG` is chosen as the keystream generator algorithm. This value is the count in bytes of the segment index portion of an `ICMGenerator`.
  - `CIPHER`: a `String` that indicates the algorithm name of the underlying symmetric key block cipher to use with the designated keystream generators. If this value is undefined, then the default cipher algorithm for the selected keystream generator algorithm shall be used (which is `Registry.RIJNDAEL_CIPHER` for both keystream generator algorithms).
  - `IBlockCipher.CIPHER_BLOCK_SIZE`: a `Integer` that indicates the block-size to use with the designated symmetric key block cipher algorithm. If this value is undefined, then the default block size for the chosen cipher is used.
  - `TAG_LENGTH`: a `Integer` that indicates the length of the resulting authentication tag, if/when the Integrity Protection service is activated.
  - `KEY_MATERIAL`: a byte array containing the user-supplied key material needed to seed the internal keystream generator.

  Parameters:
    `attributes` - the map of attributes to use for this instance.

### beginMessage

    public byte[] beginMessage()
                        throws LimitReachedException,
                               java.security.InvalidKeyException

  Signals the start of a new message to process with this `UST`.

  Returns:
    a byte array containing the representation of the Index used for this message.
  Throws:
    `LimitReachedException` - if the value of the Index has reached its allowed upper bound. To use this `UST` instance a new initialisation (with a new user-supplied key material) should occur.
    `java.security.InvalidKeyException` - if the underlying cipher, used in either or both the Integrity Protection and Confidentiality Protection functions has detected an exception.

### beginMessageWithIndex

    public void beginMessageWithIndex(int ndx)
                               throws LimitReachedException,
                                      java.security.InvalidKeyException

  Signals the start of a new message to process with this `UST` with a designated <emIndex value.

  Parameters:
    `ndx` - the Index to use with the new message.
  Throws:
    `LimitReachedException` - if the value of the Index has reached its allowed upper bound. To use this `UST` instance a new initialisation (with a new user-supplied key material) should occur.
    `java.security.InvalidKeyException` - if the underlying cipher, used in either or both the Integrity Protection and Confidentiality Protection functions has detected an exception.

### beginMessageWithIndex

    public void beginMessageWithIndex(java.math.BigInteger ndx)
                               throws LimitReachedException,
                                      java.security.InvalidKeyException

  Signals the start of a new message to process with this `UST` with a designated <emIndex value.

  Parameters:
    `ndx` - the Index to use with the new message.
  Throws:
    `LimitReachedException` - if the value of the Index has reached its allowed upper bound. To use this `UST` instance a new initialisation (with a new user-supplied key material) should occur.
    `java.security.InvalidKeyException` - if the underlying cipher, used in either or both the Integrity Protection and Confidentiality Protection functions has detected an exception.

### doClear

    public void doClear(byte[] in,
                        int offset,
                        int length)

  Process the Clear part of the message.

  Parameters:
    `in` - a byte array containing the Clear part of the message.
    `offset` - the starting index in `in` where the Clear message bytes should be considered.
    `length` - the count of bytes in `in`, starting from `offset` to consider.
  Throws:
    `java.lang.IllegalStateException` - if no start-of-message method has been invoked earlier or the Integrity Protection service has not been activated.

### doOpaque

    public void doOpaque(byte[] in,
                         int inOffset,
                         int length,
                         byte[] out,
                         int outOffset)
                  throws LimitReachedException

  Process the Opaque part of the message.

  Parameters:
    `in` - a byte array containing the Clear part of the message.
    `inOffset` - the starting index in `in` where the Opaque message bytes should be considered.
    `length` - the count of bytes in `in`, starting from `inOffset` to consider.
    `out` - the byte array where the enciphered opaque message should be stored.
    `outOffset` - the starting offset in `out` where the enciphered bytes should be stored.
  Throws:
    `java.lang.IllegalStateException` - if no start-of-message method has been invoked earlier.
    `LimitReachedException` - if one or both of the underlying keystream generators have reached their limit.

### endMessage

    public byte[] endMessage()

  Signals the end of the message transformation.

  Returns:
    the authentication tag bytes, if and when the Integrity Protection service was specified; otherwise a 0-long byte array is returned.
  Throws:
    `java.lang.IllegalStateException` - if no start-of-message method has been invoked earlier.

### reset

    public void reset()

  Reset this instance and prepare for processing a new message.

### selfTest

    public boolean selfTest()

For the latest news and information visit The GNU Crypto project

Copyright © 2001, 2002, 2003, 2004 Free Software Foundation, Inc.