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