EMMA Coverage Report (generated Wed Aug 16 18:51:55 GMT 2006)
[all classes][gnu.javax.crypto.mode]

COVERAGE SUMMARY FOR SOURCE FILE [BaseMode.java]

nameclass, %method, %block, %line, %
BaseMode.java100% (1/1)75%  (9/12)84%  (321/381)85%  (75.5/89)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BaseMode100% (1/1)75%  (9/12)84%  (321/381)85%  (75.5/89)
BaseMode (String, IBlockCipher, int): void 100% (1/1)100% (20/20)100% (7/7)
blockSizes (): Iterator 100% (1/1)100% (14/14)100% (3/3)
currentBlockSize (): int 100% (1/1)64%  (7/11)67%  (2/3)
defaultBlockSize (): int 0%   (0/1)0%   (0/3)0%   (0/1)
defaultKeySize (): int 0%   (0/1)0%   (0/4)0%   (0/1)
init (Map): void 100% (1/1)80%  (64/80)84%  (16.9/20)
keySizes (): Iterator 100% (1/1)100% (4/4)100% (1/1)
name (): String 0%   (0/1)0%   (0/15)0%   (0/2)
reset (): void 100% (1/1)87%  (20/23)98%  (5.9/6)
selfTest (): boolean 100% (1/1)94%  (29/31)83%  (5/6)
testSymmetry (int, int): boolean 100% (1/1)96%  (137/143)90%  (28/31)
update (byte [], int, byte [], int): void 100% (1/1)79%  (26/33)85%  (6.8/8)

1/* BaseMode.java -- 
2   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
3 
4This file is a part of GNU Classpath.
5 
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or (at
9your option) any later version.
10 
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14General Public License for more details.
15 
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; if not, write to the Free Software
18Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19USA
20 
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library.  Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25 
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module.  An independent module is a module which is not derived from
33or based on this library.  If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so.  If you do not wish to do so, delete this
36exception statement from your version.  */
37 
38 
39package gnu.javax.crypto.mode;
40 
41import gnu.javax.crypto.cipher.IBlockCipher;
42 
43import java.security.InvalidKeyException;
44import java.util.ArrayList;
45import java.util.Arrays;
46import java.util.Collections;
47import java.util.HashMap;
48import java.util.Iterator;
49import java.util.Map;
50 
51/**
52 * A basic abstract class to facilitate implementing block cipher modes of
53 * operations.
54 */
55public abstract class BaseMode
56    implements IMode
57{
58  /** The canonical name prefix of this mode. */
59  protected String name;
60  /** The state indicator of this instance. */
61  protected int state;
62  /** The underlying block cipher implementation. */
63  protected IBlockCipher cipher;
64  /** The block size, in bytes, to operate the underlying block cipher in. */
65  protected int cipherBlockSize;
66  /** The block size, in bytes, in which to operate the mode instance. */
67  protected int modeBlockSize;
68  /** The initialisation vector value. */
69  protected byte[] iv;
70  /** The instance lock. */
71  protected Object lock = new Object();
72 
73  /**
74   * Trivial constructor for use by concrete subclasses.
75   * 
76   * @param name the canonical name prefix of this mode.
77   * @param underlyingCipher the implementation of the underlying cipher.
78   * @param cipherBlockSize the block size, in bytes, in which to operate the
79   *          underlying cipher.
80   */
81  protected BaseMode(String name, IBlockCipher underlyingCipher,
82                     int cipherBlockSize)
83  {
84    super();
85 
86    this.name = name;
87    this.cipher = underlyingCipher;
88    this.cipherBlockSize = cipherBlockSize;
89    state = -1;
90  }
91 
92  public void update(byte[] in, int inOffset, byte[] out, int outOffset)
93      throws IllegalStateException
94  {
95    synchronized (lock)
96      {
97        switch (state)
98          {
99          case ENCRYPTION:
100            encryptBlock(in, inOffset, out, outOffset);
101            break;
102          case DECRYPTION:
103            decryptBlock(in, inOffset, out, outOffset);
104            break;
105          default:
106            throw new IllegalStateException();
107          }
108      }
109  }
110 
111  public String name()
112  {
113    return new StringBuffer(name).append('(').append(cipher.name()).append(')')
114        .toString();
115  }
116 
117  /**
118   * Returns the default value, in bytes, of the mode's block size. This value
119   * is part of the construction arguments passed to the Factory methods in
120   * {@link ModeFactory}. Unless changed by an invocation of any of the
121   * <code>init()</code> methods, a <i>Mode</i> instance would operate with
122   * the same block size as its underlying block cipher. As mentioned earlier,
123   * the block size of the underlying block cipher itself is specified in one of
124   * the method(s) available in the factory class.
125   * 
126   * @return the default value, in bytes, of the mode's block size.
127   * @see ModeFactory
128   */
129  public int defaultBlockSize()
130  {
131    return cipherBlockSize;
132  }
133 
134  /**
135   * Returns the default value, in bytes, of the underlying block cipher key
136   * size.
137   * 
138   * @return the default value, in bytes, of the underlying cipher's key size.
139   */
140  public int defaultKeySize()
141  {
142    return cipher.defaultKeySize();
143  }
144 
145  /**
146   * Returns an {@link Iterator} over the supported block sizes. Each element
147   * returned by this object is an {@link Integer}.
148   * <p>
149   * The default behaviour is to return an iterator with just one value, which
150   * is that currently configured for the underlying block cipher. Concrete
151   * implementations may override this behaviour to signal their ability to
152   * support other values.
153   * 
154   * @return an {@link Iterator} over the supported block sizes.
155   */
156  public Iterator blockSizes()
157  {
158    ArrayList al = new ArrayList();
159    al.add(Integer.valueOf(cipherBlockSize));
160    return Collections.unmodifiableList(al).iterator();
161  }
162 
163  /**
164   * Returns an {@link Iterator} over the supported underlying block cipher key
165   * sizes. Each element returned by this object is an instance of
166   * {@link Integer}.
167   * 
168   * @return an {@link Iterator} over the supported key sizes.
169   */
170  public Iterator keySizes()
171  {
172    return cipher.keySizes();
173  }
174 
175  public void init(Map attributes) throws InvalidKeyException,
176      IllegalStateException
177  {
178    synchronized (lock)
179      {
180        if (state != -1)
181          throw new IllegalStateException();
182        Integer want = (Integer) attributes.get(STATE);
183        if (want != null)
184          {
185            switch (want.intValue())
186              {
187              case ENCRYPTION:
188                state = ENCRYPTION;
189                break;
190              case DECRYPTION:
191                state = DECRYPTION;
192                break;
193              default:
194                throw new IllegalArgumentException();
195              }
196          }
197        Integer bs = (Integer) attributes.get(MODE_BLOCK_SIZE);
198        modeBlockSize = (bs == null ? cipherBlockSize : bs.intValue());
199        byte[] iv = (byte[]) attributes.get(IV);
200        if (iv != null)
201          this.iv = (byte[]) iv.clone();
202        else
203          this.iv = new byte[modeBlockSize];
204        cipher.init(attributes);
205        setup();
206      }
207  }
208 
209  public int currentBlockSize()
210  {
211    if (state == -1)
212      throw new IllegalStateException();
213    return modeBlockSize;
214  }
215 
216  public void reset()
217  {
218    synchronized (lock)
219      {
220        state = -1;
221        iv = null;
222        cipher.reset();
223        teardown();
224      }
225  }
226 
227  public boolean selfTest()
228  {
229    int ks;
230    Iterator bit;
231    for (Iterator kit = keySizes(); kit.hasNext();)
232      {
233        ks = ((Integer) kit.next()).intValue();
234        for (bit = blockSizes(); bit.hasNext();)
235          if (! testSymmetry(ks, ((Integer) bit.next()).intValue()))
236            return false;
237      }
238    return true;
239  }
240 
241  public abstract Object clone();
242 
243  /** The initialisation phase of the concrete mode implementation. */
244  public abstract void setup();
245 
246  /** The termination phase of the concrete mode implementation. */
247  public abstract void teardown();
248 
249  public abstract void encryptBlock(byte[] in, int i, byte[] out, int o);
250 
251  public abstract void decryptBlock(byte[] in, int i, byte[] out, int o);
252 
253  private boolean testSymmetry(int ks, int bs)
254  {
255    try
256      {
257        IMode mode = (IMode) this.clone();
258        byte[] iv = new byte[cipherBlockSize]; // all zeroes
259        byte[] k = new byte[ks];
260        int i;
261        for (i = 0; i < ks; i++)
262          k[i] = (byte) i;
263        int blockCount = 5;
264        int limit = blockCount * bs;
265        byte[] pt = new byte[limit];
266        for (i = 0; i < limit; i++)
267          pt[i] = (byte) i;
268        byte[] ct = new byte[limit];
269        byte[] cpt = new byte[limit];
270        Map map = new HashMap();
271        map.put(KEY_MATERIAL, k);
272        map.put(CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize));
273        map.put(STATE, Integer.valueOf(ENCRYPTION));
274        map.put(IV, iv);
275        map.put(MODE_BLOCK_SIZE, Integer.valueOf(bs));
276        mode.reset();
277        mode.init(map);
278        for (i = 0; i < blockCount; i++)
279          mode.update(pt, i * bs, ct, i * bs);
280        mode.reset();
281        map.put(STATE, Integer.valueOf(DECRYPTION));
282        mode.init(map);
283        for (i = 0; i < blockCount; i++)
284          mode.update(ct, i * bs, cpt, i * bs);
285        return Arrays.equals(pt, cpt);
286      }
287    catch (Exception x)
288      {
289        x.printStackTrace(System.err);
290        return false;
291      }
292  }
293}

[all classes][gnu.javax.crypto.mode]
EMMA 2.0.6427 (unsupported private build) (C) Vladimir Roubtsov