1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.crypto.modes;
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.BlockCipher;
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.CipherParameters;
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.DataLengthException;
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.ParametersWithIV;
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher.
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class CBCBlockCipher
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    implements BlockCipher
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private byte[]          IV;
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private byte[]          cbcV;
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private byte[]          cbcNextV;
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int             blockSize;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private BlockCipher     cipher = null;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean         encrypting;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Basic constructor.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param cipher the block cipher to be used as the basis of chaining.
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CBCBlockCipher(
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BlockCipher cipher)
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.cipher = cipher;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.blockSize = cipher.getBlockSize();
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.IV = new byte[blockSize];
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.cbcV = new byte[blockSize];
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.cbcNextV = new byte[blockSize];
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * return the underlying block cipher that we are wrapping.
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the underlying block cipher that we are wrapping.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public BlockCipher getUnderlyingCipher()
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return cipher;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initialise the cipher and, possibly, the initialisation vector (IV).
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If an IV isn't passed as part of the parameter, the IV will be all zeros.
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param encrypting if true the cipher is initialised for
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  encryption, if false for decryption.
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param params the key and other data required by the cipher.
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception IllegalArgumentException if the params argument is
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * inappropriate.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void init(
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean             encrypting,
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CipherParameters    params)
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throws IllegalArgumentException
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.encrypting = encrypting;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (params instanceof ParametersWithIV)
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ParametersWithIV ivParam = (ParametersWithIV)params;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                byte[]      iv = ivParam.getIV();
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (iv.length != blockSize)
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalArgumentException("initialisation vector must be the same length as block size");
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.arraycopy(iv, 0, IV, 0, iv.length);
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                reset();
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cipher.init(encrypting, ivParam.getParameters());
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                reset();
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cipher.init(encrypting, params);
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * return the algorithm name and mode.
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the name of the underlying algorithm followed by "/CBC".
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getAlgorithmName()
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return cipher.getAlgorithmName() + "/CBC";
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * return the block size of the underlying cipher.
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the block size of the underlying cipher.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getBlockSize()
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return cipher.getBlockSize();
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Process one block of input from the array in and write it to
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the out array.
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param in the array containing the input data.
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inOff offset into the in array the data starts at.
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param out the array the output data will be copied into.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outOff the offset into the out array the output will start at.
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception DataLengthException if there isn't enough data in in, or
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * space in out.
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception IllegalStateException if the cipher isn't initialised.
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes processed and produced.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int processBlock(
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      in,
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         inOff,
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      out,
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         outOff)
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throws DataLengthException, IllegalStateException
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (encrypting) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff);
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * reset the chaining vector back to the IV and reset the underlying
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * cipher.
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void reset()
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(IV, 0, cbcV, 0, IV.length);
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cipher.reset();
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Do the appropriate chaining step for CBC mode encryption.
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param in the array containing the data to be encrypted.
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inOff offset into the in array the data starts at.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param out the array the encrypted data will be copied into.
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outOff the offset into the out array the output will start at.
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception DataLengthException if there isn't enough data in in, or
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * space in out.
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception IllegalStateException if the cipher isn't initialised.
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes processed and produced.
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int encryptBlock(
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      in,
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         inOff,
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      out,
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         outOff)
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throws DataLengthException, IllegalStateException
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((inOff + blockSize) > in.length)
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DataLengthException("input buffer too short");
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * XOR the cbcV and the input,
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * then encrypt the cbcV
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < blockSize; i++)
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cbcV[i] ^= in[inOff + i];
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int length = cipher.processBlock(cbcV, 0, out, outOff);
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * copy ciphertext to cbcV
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(out, outOff, cbcV, 0, cbcV.length);
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return length;
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Do the appropriate chaining step for CBC mode decryption.
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param in the array containing the data to be decrypted.
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inOff offset into the in array the data starts at.
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param out the array the decrypted data will be copied into.
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outOff the offset into the out array the output will start at.
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception DataLengthException if there isn't enough data in in, or
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * space in out.
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception IllegalStateException if the cipher isn't initialised.
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes processed and produced.
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int decryptBlock(
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      in,
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         inOff,
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]      out,
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int         outOff)
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throws DataLengthException, IllegalStateException
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((inOff + blockSize) > in.length)
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DataLengthException("input buffer too short");
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(in, inOff, cbcNextV, 0, blockSize);
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int length = cipher.processBlock(in, inOff, out, outOff);
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * XOR the cbcV and the output
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < blockSize; i++)
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out[outOff + i] ^= cbcV[i];
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * swap the back up buffer into next position
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[]  tmp;
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tmp = cbcV;
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cbcV = cbcNextV;
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cbcNextV = tmp;
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return length;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
234