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 }