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