1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54:
55: import ;
56:
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63:
64:
68: public class ARCFourSpi
69: extends CipherSpi
70: {
71: private IRandom keystream;
72:
73: public ARCFourSpi()
74: {
75: super();
76: keystream = PRNGFactory.getInstance(Registry.ARCFOUR_PRNG);
77: }
78:
79: protected int engineGetBlockSize()
80: {
81: return 0;
82: }
83:
84: protected void engineSetMode(String s) throws NoSuchAlgorithmException
85: {
86:
87: }
88:
89: protected void engineSetPadding(String s) throws NoSuchPaddingException
90: {
91:
92: }
93:
94: protected byte[] engineGetIV()
95: {
96: return null;
97: }
98:
99: protected int engineGetOutputSize(int in)
100: {
101: return in;
102: }
103:
104: protected AlgorithmParameters engineGetParameters()
105: {
106: return null;
107: }
108:
109: protected void engineInit(int mode, Key key, SecureRandom r)
110: throws InvalidKeyException
111: {
112: if (mode != Cipher.ENCRYPT_MODE && mode != Cipher.DECRYPT_MODE)
113: throw new IllegalArgumentException(
114: "arcfour is for encryption or decryption only");
115: if (key == null || ! key.getFormat().equalsIgnoreCase("RAW"))
116: throw new InvalidKeyException("key must be non-null raw bytes");
117: HashMap attrib = new HashMap();
118: attrib.put(ARCFour.ARCFOUR_KEY_MATERIAL, key.getEncoded());
119: keystream.init(attrib);
120: }
121:
122: protected void engineInit(int mode, Key key, AlgorithmParameterSpec p,
123: SecureRandom r) throws InvalidKeyException,
124: InvalidAlgorithmParameterException
125: {
126: engineInit(mode, key, r);
127: }
128:
129: protected void engineInit(int mode, Key key, AlgorithmParameters p,
130: SecureRandom r) throws InvalidKeyException,
131: InvalidAlgorithmParameterException
132: {
133: engineInit(mode, key, r);
134: }
135:
136: protected byte[] engineUpdate(byte[] in, int offset, int length)
137: {
138: if (length < 0 || offset < 0 || length + offset > in.length)
139: throw new ArrayIndexOutOfBoundsException();
140: byte[] result = new byte[length];
141: try
142: {
143: for (int i = 0; i < length; i++)
144: result[i] = (byte)(in[i + offset] ^ keystream.nextByte());
145: }
146: catch (LimitReachedException wontHappen)
147: {
148: }
149: return result;
150: }
151:
152: protected int engineUpdate(byte[] in, int inOffset, int length, byte[] out,
153: int outOffset) throws ShortBufferException
154: {
155: if (length < 0 || inOffset < 0 || length + inOffset > in.length
156: || outOffset < 0)
157: throw new ArrayIndexOutOfBoundsException();
158: if (outOffset + length > out.length)
159: throw new ShortBufferException();
160: try
161: {
162: for (int i = 0; i < length; i++)
163: out[i + outOffset] = (byte)(in[i + inOffset] ^ keystream.nextByte());
164: }
165: catch (LimitReachedException wontHappen)
166: {
167: }
168: return length;
169: }
170:
171: protected byte[] engineDoFinal(byte[] in, int offset, int length)
172: throws IllegalBlockSizeException, BadPaddingException
173: {
174: return engineUpdate(in, offset, length);
175: }
176:
177: protected int engineDoFinal(byte[] in, int inOffset, int length, byte[] out,
178: int outOffset) throws ShortBufferException,
179: IllegalBlockSizeException, BadPaddingException
180: {
181: return engineUpdate(in, inOffset, length, out, outOffset);
182: }
183: }