• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
3  * Please refer to the LICENSE.txt for licensing details.
4  */
5 package ch.ethz.ssh2.crypto.cipher;
6 
7 /**
8  * CBCMode.
9  *
10  * @author Christian Plattner
11  * @version 2.50, 03/15/10
12  */
13 public class CBCMode implements BlockCipher
14 {
15 	BlockCipher tc;
16 	int blockSize;
17 	boolean doEncrypt;
18 
19 	byte[] cbc_vector;
20 	byte[] tmp_vector;
21 
init(boolean forEncryption, byte[] key)22 	public void init(boolean forEncryption, byte[] key)
23 	{
24 	}
25 
CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)26 	public CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)
27 			throws IllegalArgumentException
28 	{
29 		this.tc = tc;
30 		this.blockSize = tc.getBlockSize();
31 		this.doEncrypt = doEncrypt;
32 
33 		if (this.blockSize != iv.length)
34 			throw new IllegalArgumentException("IV must be " + blockSize
35 					+ " bytes long! (currently " + iv.length + ")");
36 
37 		this.cbc_vector = new byte[blockSize];
38 		this.tmp_vector = new byte[blockSize];
39 		System.arraycopy(iv, 0, cbc_vector, 0, blockSize);
40 	}
41 
getBlockSize()42 	public int getBlockSize()
43 	{
44 		return blockSize;
45 	}
46 
encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)47 	private void encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
48 	{
49 		for (int i = 0; i < blockSize; i++)
50 			cbc_vector[i] ^= src[srcoff + i];
51 
52 		tc.transformBlock(cbc_vector, 0, dst, dstoff);
53 
54 		System.arraycopy(dst, dstoff, cbc_vector, 0, blockSize);
55 	}
56 
decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)57 	private void decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
58 	{
59 		/* Assume the worst, src and dst are overlapping... */
60 
61 		System.arraycopy(src, srcoff, tmp_vector, 0, blockSize);
62 
63 		tc.transformBlock(src, srcoff, dst, dstoff);
64 
65 		for (int i = 0; i < blockSize; i++)
66 			dst[dstoff + i] ^= cbc_vector[i];
67 
68 		/* ...that is why we need a tmp buffer. */
69 
70 		byte[] swap = cbc_vector;
71 		cbc_vector = tmp_vector;
72 		tmp_vector = swap;
73 	}
74 
transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)75 	public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
76 	{
77 		if (doEncrypt)
78 			encryptBlock(src, srcoff, dst, dstoff);
79 		else
80 			decryptBlock(src, srcoff, dst, dstoff);
81 	}
82 }
83