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.func_71804_b()];
022            this.field_71812_b = new byte[par1BlockCipher.func_71804_b()];
023            this.field_71813_c = new byte[par1BlockCipher.func_71804_b()];
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.func_71779_a();
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.func_71780_b() != null)
052                {
053                    this.field_71811_e.func_71805_a(true, var3.func_71780_b());
054                }
055            }
056            else
057            {
058                this.func_71803_c();
059                this.field_71811_e.func_71805_a(true, par2CipherParameters);
060            }
061        }
062    
063        public String func_71802_a()
064        {
065            return this.field_71811_e.func_71802_a() + "/CFB" + this.field_71810_d * 8;
066        }
067    
068        public int func_71804_b()
069        {
070            return this.field_71810_d;
071        }
072    
073        public int func_71806_a(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
074        {
075            return this.field_71809_f ? this.func_71807_b(par1ArrayOfByte, par2, par3ArrayOfByte, par4) : this.func_71808_c(par1ArrayOfByte, par2, par3ArrayOfByte, par4);
076        }
077    
078        public int func_71807_b(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
079        {
080            if (par2 + this.field_71810_d > par1ArrayOfByte.length)
081            {
082                throw new DataLengthException("input buffer too short");
083            }
084            else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
085            {
086                throw new DataLengthException("output buffer too short");
087            }
088            else
089            {
090                this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
091    
092                for (int var5 = 0; var5 < this.field_71810_d; ++var5)
093                {
094                    par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
095                }
096    
097                System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
098                System.arraycopy(par3ArrayOfByte, par4, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
099                return this.field_71810_d;
100            }
101        }
102    
103        public int func_71808_c(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
104        {
105            if (par2 + this.field_71810_d > par1ArrayOfByte.length)
106            {
107                throw new DataLengthException("input buffer too short");
108            }
109            else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
110            {
111                throw new DataLengthException("output buffer too short");
112            }
113            else
114            {
115                this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
116                System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
117                System.arraycopy(par1ArrayOfByte, par2, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
118    
119                for (int var5 = 0; var5 < this.field_71810_d; ++var5)
120                {
121                    par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
122                }
123    
124                return this.field_71810_d;
125            }
126        }
127    
128        public void func_71803_c()
129        {
130            System.arraycopy(this.field_71814_a, 0, this.field_71812_b, 0, this.field_71814_a.length);
131            this.field_71811_e.func_71803_c();
132        }
133    }