1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50:
54: public abstract class BaseCipher
55: implements IBlockCipher, IBlockCipherSpi
56: {
57: private static final Logger log = Logger.getLogger(BaseCipher.class.getName());
58:
59: protected String name;
60:
61: protected int defaultBlockSize;
62:
63: protected int defaultKeySize;
64:
65: protected int currentBlockSize;
66:
67: protected transient Object currentKey;
68:
69: protected Object lock = new Object();
70:
71:
78: protected BaseCipher(String name, int defaultBlockSize, int defaultKeySize)
79: {
80: super();
81:
82: this.name = name;
83: this.defaultBlockSize = defaultBlockSize;
84: this.defaultKeySize = defaultKeySize;
85: }
86:
87: public abstract Object clone();
88:
89: public String name()
90: {
91: StringBuffer sb = new StringBuffer(name).append('-');
92: if (currentKey == null)
93: sb.append(String.valueOf(8 * defaultBlockSize));
94: else
95: sb.append(String.valueOf(8 * currentBlockSize));
96: return sb.toString();
97: }
98:
99: public int defaultBlockSize()
100: {
101: return defaultBlockSize;
102: }
103:
104: public int defaultKeySize()
105: {
106: return defaultKeySize;
107: }
108:
109: public void init(Map attributes) throws InvalidKeyException
110: {
111: synchronized (lock)
112: {
113: if (currentKey != null)
114: throw new IllegalStateException();
115: Integer bs = (Integer) attributes.get(CIPHER_BLOCK_SIZE);
116: if (bs == null)
117: {
118: if (currentBlockSize == 0)
119: currentBlockSize = defaultBlockSize;
120:
121: }
122: else
123: {
124: currentBlockSize = bs.intValue();
125:
126: Iterator it;
127: boolean ok = false;
128: for (it = blockSizes(); it.hasNext();)
129: {
130: ok = (currentBlockSize == ((Integer) it.next()).intValue());
131: if (ok)
132: break;
133: }
134: if (! ok)
135: throw new IllegalArgumentException(IBlockCipher.CIPHER_BLOCK_SIZE);
136: }
137: byte[] k = (byte[]) attributes.get(KEY_MATERIAL);
138: currentKey = makeKey(k, currentBlockSize);
139: }
140: }
141:
142: public int currentBlockSize()
143: {
144: if (currentKey == null)
145: throw new IllegalStateException();
146: return currentBlockSize;
147: }
148:
149: public void reset()
150: {
151: synchronized (lock)
152: {
153: currentKey = null;
154: }
155: }
156:
157: public void encryptBlock(byte[] in, int inOffset, byte[] out, int outOffset)
158: throws IllegalStateException
159: {
160: synchronized (lock)
161: {
162: if (currentKey == null)
163: throw new IllegalStateException();
164: encrypt(in, inOffset, out, outOffset, currentKey, currentBlockSize);
165: }
166: }
167:
168: public void decryptBlock(byte[] in, int inOffset, byte[] out, int outOffset)
169: throws IllegalStateException
170: {
171: synchronized (lock)
172: {
173: if (currentKey == null)
174: throw new IllegalStateException();
175: decrypt(in, inOffset, out, outOffset, currentKey, currentBlockSize);
176: }
177: }
178:
179: public boolean selfTest()
180: {
181: int ks;
182: Iterator bit;
183:
184: for (Iterator kit = keySizes(); kit.hasNext();)
185: {
186: ks = ((Integer) kit.next()).intValue();
187: for (bit = blockSizes(); bit.hasNext();)
188: if (! testSymmetry(ks, ((Integer) bit.next()).intValue()))
189: return false;
190: }
191: return true;
192: }
193:
194: private boolean testSymmetry(int ks, int bs)
195: {
196: try
197: {
198: byte[] kb = new byte[ks];
199: byte[] pt = new byte[bs];
200: byte[] ct = new byte[bs];
201: byte[] cpt = new byte[bs];
202: int i;
203: for (i = 0; i < ks; i++)
204: kb[i] = (byte) i;
205: for (i = 0; i < bs; i++)
206: pt[i] = (byte) i;
207: Object k = makeKey(kb, bs);
208: encrypt(pt, 0, ct, 0, k, bs);
209: decrypt(ct, 0, cpt, 0, k, bs);
210: return Arrays.equals(pt, cpt);
211: }
212: catch (Exception x)
213: {
214: if (Configuration.DEBUG)
215: log.log(Level.FINE, "Exception in testSymmetry() for " + name(), x);
216: return false;
217: }
218: }
219:
220: protected boolean testKat(byte[] kb, byte[] ct)
221: {
222: return testKat(kb, ct, new byte[ct.length]);
223: }
224:
225: protected boolean testKat(byte[] kb, byte[] ct, byte[] pt)
226: {
227: try
228: {
229: int bs = pt.length;
230: byte[] t = new byte[bs];
231: Object k = makeKey(kb, bs);
232:
233: encrypt(pt, 0, t, 0, k, bs);
234: if (! Arrays.equals(t, ct))
235: return false;
236:
237: decrypt(t, 0, t, 0, k, bs);
238: return Arrays.equals(t, pt);
239: }
240: catch (Exception x)
241: {
242: if (Configuration.DEBUG)
243: log.log(Level.FINE, "Exception in testKat() for " + name(), x);
244: return false;
245: }
246: }
247: }