1package 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 */
7public 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 params 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