001 package org.bouncycastle.crypto.modes;
002
003 import org.bouncycastle.crypto.BlockCipher;
004 import org.bouncycastle.crypto.CipherParameters;
005 import org.bouncycastle.crypto.DataLengthException;
006 import org.bouncycastle.crypto.params.ParametersWithIV;
007
008 public class CFBBlockCipher implements BlockCipher
009 {
010 private byte[] field_71814_a;
011 private byte[] field_71812_b;
012 private byte[] field_71813_c;
013 private int field_71810_d;
014 private BlockCipher field_71811_e = null;
015 private boolean field_71809_f;
016
017 public CFBBlockCipher(BlockCipher par1BlockCipher, int par2)
018 {
019 this.field_71811_e = par1BlockCipher;
020 this.field_71810_d = par2 / 8;
021 this.field_71814_a = new byte[par1BlockCipher.getBlockSize()];
022 this.field_71812_b = new byte[par1BlockCipher.getBlockSize()];
023 this.field_71813_c = new byte[par1BlockCipher.getBlockSize()];
024 }
025
026 public void func_71805_a(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException
027 {
028 this.field_71809_f = par1;
029
030 if (par2CipherParameters instanceof ParametersWithIV)
031 {
032 ParametersWithIV var3 = (ParametersWithIV)par2CipherParameters;
033 byte[] var4 = var3.getIV();
034
035 if (var4.length < this.field_71814_a.length)
036 {
037 System.arraycopy(var4, 0, this.field_71814_a, this.field_71814_a.length - var4.length, var4.length);
038
039 for (int var5 = 0; var5 < this.field_71814_a.length - var4.length; ++var5)
040 {
041 this.field_71814_a[var5] = 0;
042 }
043 }
044 else
045 {
046 System.arraycopy(var4, 0, this.field_71814_a, 0, this.field_71814_a.length);
047 }
048
049 this.func_71803_c();
050
051 if (var3.getParameters() != null)
052 {
053 this.field_71811_e.func_71805_a(true, var3.getParameters());
054 }
055 }
056 else
057 {
058 this.func_71803_c();
059 this.field_71811_e.func_71805_a(true, par2CipherParameters);
060 }
061 }
062
063 /**
064 * Return the name of the algorithm the cipher implements.
065 */
066 public String getAlgorithmName()
067 {
068 return this.field_71811_e.getAlgorithmName() + "/CFB" + this.field_71810_d * 8;
069 }
070
071 /**
072 * Return the block size for this cipher (in bytes).
073 */
074 public int getBlockSize()
075 {
076 return this.field_71810_d;
077 }
078
079 public int func_71806_a(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
080 {
081 return this.field_71809_f ? this.func_71807_b(par1ArrayOfByte, par2, par3ArrayOfByte, par4) : this.func_71808_c(par1ArrayOfByte, par2, par3ArrayOfByte, par4);
082 }
083
084 public int func_71807_b(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
085 {
086 if (par2 + this.field_71810_d > par1ArrayOfByte.length)
087 {
088 throw new DataLengthException("input buffer too short");
089 }
090 else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
091 {
092 throw new DataLengthException("output buffer too short");
093 }
094 else
095 {
096 this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
097
098 for (int var5 = 0; var5 < this.field_71810_d; ++var5)
099 {
100 par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
101 }
102
103 System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
104 System.arraycopy(par3ArrayOfByte, par4, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
105 return this.field_71810_d;
106 }
107 }
108
109 public int func_71808_c(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
110 {
111 if (par2 + this.field_71810_d > par1ArrayOfByte.length)
112 {
113 throw new DataLengthException("input buffer too short");
114 }
115 else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
116 {
117 throw new DataLengthException("output buffer too short");
118 }
119 else
120 {
121 this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
122 System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
123 System.arraycopy(par1ArrayOfByte, par2, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
124
125 for (int var5 = 0; var5 < this.field_71810_d; ++var5)
126 {
127 par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
128 }
129
130 return this.field_71810_d;
131 }
132 }
133
134 public void func_71803_c()
135 {
136 System.arraycopy(this.field_71814_a, 0, this.field_71812_b, 0, this.field_71814_a.length);
137 this.field_71811_e.func_71803_c();
138 }
139 }