0
|
1 package com.trilead.ssh2.crypto.cipher;
|
|
2
|
|
3 /**
|
|
4 * CBCMode.
|
|
5 *
|
|
6 * @author Christian Plattner, plattner@trilead.com
|
|
7 * @version $Id: CBCMode.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
|
|
8 */
|
|
9 public class CBCMode implements BlockCipher {
|
|
10 BlockCipher tc;
|
|
11 int blockSize;
|
|
12 boolean doEncrypt;
|
|
13
|
|
14 byte[] cbc_vector;
|
|
15 byte[] tmp_vector;
|
|
16
|
|
17 public void init(boolean forEncryption, byte[] key) {
|
|
18 }
|
|
19
|
|
20 public CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)
|
|
21 throws IllegalArgumentException {
|
|
22 this.tc = tc;
|
|
23 this.blockSize = tc.getBlockSize();
|
|
24 this.doEncrypt = doEncrypt;
|
|
25
|
|
26 if (this.blockSize != iv.length)
|
|
27 throw new IllegalArgumentException("IV must be " + blockSize
|
|
28 + " bytes long! (currently " + iv.length + ")");
|
|
29
|
|
30 this.cbc_vector = new byte[blockSize];
|
|
31 this.tmp_vector = new byte[blockSize];
|
|
32 System.arraycopy(iv, 0, cbc_vector, 0, blockSize);
|
|
33 }
|
|
34
|
|
35 public int getBlockSize() {
|
|
36 return blockSize;
|
|
37 }
|
|
38
|
|
39 private void encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
|
|
40 for (int i = 0; i < blockSize; i++)
|
|
41 cbc_vector[i] ^= src[srcoff + i];
|
|
42
|
|
43 tc.transformBlock(cbc_vector, 0, dst, dstoff);
|
|
44 System.arraycopy(dst, dstoff, cbc_vector, 0, blockSize);
|
|
45 }
|
|
46
|
|
47 private void decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
|
|
48 /* Assume the worst, src and dst are overlapping... */
|
|
49 System.arraycopy(src, srcoff, tmp_vector, 0, blockSize);
|
|
50 tc.transformBlock(src, srcoff, dst, dstoff);
|
|
51
|
|
52 for (int i = 0; i < blockSize; i++)
|
|
53 dst[dstoff + i] ^= cbc_vector[i];
|
|
54
|
|
55 /* ...that is why we need a tmp buffer. */
|
|
56 byte[] swap = cbc_vector;
|
|
57 cbc_vector = tmp_vector;
|
|
58 tmp_vector = swap;
|
|
59 }
|
|
60
|
|
61 public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
|
|
62 if (doEncrypt)
|
|
63 encryptBlock(src, srcoff, dst, dstoff);
|
|
64 else
|
|
65 decryptBlock(src, srcoff, dst, dstoff);
|
|
66 }
|
|
67 }
|