1    package org.bouncycastle.crypto;
2    
3    /**
4     * a wrapper for block ciphers with a single byte block size, so that they
5     * can be treated like stream ciphers.
6     */
7    public class StreamBlockCipher
8        implements StreamCipher
9    {
10       private BlockCipher  cipher;
11   
12       private byte[]  oneByte = new byte[1];
13   
14       /**
15        * basic constructor.
16        *
17        * @param cipher the block cipher to be wrapped.
18        * @exception IllegalArgumentException if the cipher has a block size other than
19        * one.
20        */
21       public StreamBlockCipher(
22           BlockCipher cipher)
23       {
24           if (cipher.getBlockSize() != 1)
25           {
26               throw new IllegalArgumentException("block cipher block size != 1.");
27           }
28   
29           this.cipher = cipher;
30       }
31   
32       /**
33        * initialise the underlying cipher.
34        *
35        * @param forEncryption true if we are setting up for encryption, false otherwise.
36        * @param param the necessary parameters for the underlying cipher to be initialised.
37        */
38       public void init(
39           boolean forEncryption,
40           CipherParameters params)
41       {
42           cipher.init(forEncryption, params);
43       }
44   
45       /**
46        * return the name of the algorithm we are wrapping.
47        *
48        * @return the name of the algorithm we are wrapping.
49        */
50       public String getAlgorithmName()
51       {
52           return cipher.getAlgorithmName();
53       }
54   
55       /**
56        * encrypt/decrypt a single byte returning the result.
57        *
58        * @param in the byte to be processed.
59        * @return the result of processing the input byte.
60        */
61       public byte returnByte(
62           byte    in)
63       {
64           oneByte[0] = in;
65   
66           cipher.processBlock(oneByte, 0, oneByte, 0);
67   
68           return oneByte[0];
69       }
70   
71       /**
72        * process a block of bytes from in putting the result into out.
73        * 
74        * @param in the input byte array.
75        * @param inOff the offset into the in array where the data to be processed starts.
76        * @param len the number of bytes to be processed.
77        * @param out the output buffer the processed bytes go into.   
78        * @param outOff the offset into the output byte array the processed data stars at.
79        * @exception DataLengthException if the output buffer is too small.
80        */
81       public void processBytes(
82           byte[]  in,
83           int     inOff,
84           int     len,
85           byte[]  out,
86           int     outOff)
87           throws DataLengthException
88       {
89           if (outOff + len > out.length)
90           {
91               throw new DataLengthException("output buffer too small in processBytes()");
92           }
93   
94           for (int i = 0; i != len; i++)
95           {
96                   cipher.processBlock(in, inOff + i, out, outOff + i);
97           }
98       }
99   
100      /**
101       * reset the underlying cipher. This leaves it in the same state
102       * it was at after the last init (if there was one).
103       */
104      public void reset()
105      {
106          cipher.reset();
107      }
108  }
109