001: package org.bouncycastle.crypto.test;
002:
003: import java.io.BufferedReader;
004: import java.io.File;
005: import java.io.IOException;
006: import java.io.InputStream;
007: import java.io.InputStreamReader;
008: import java.util.ArrayList;
009: import java.util.Enumeration;
010: import java.util.List;
011: import java.util.zip.ZipEntry;
012: import java.util.zip.ZipFile;
013:
014: import org.bouncycastle.crypto.BlockCipher;
015: import org.bouncycastle.crypto.engines.AESEngine;
016: import org.bouncycastle.crypto.engines.AESFastEngine;
017: import org.bouncycastle.crypto.engines.AESLightEngine;
018: import org.bouncycastle.crypto.params.KeyParameter;
019: import org.bouncycastle.util.encoders.Hex;
020: import org.bouncycastle.util.test.SimpleTestResult;
021: import org.bouncycastle.util.test.Test;
022: import org.bouncycastle.util.test.TestResult;
023:
024: /**
025: * Test vectors from the NIST standard tests and Brian Gladman's vector set
026: * <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">
027: * http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
028: */
029: public class AESVectorFileTest implements Test {
030:
031: private int countOfTests = 0;
032: private int testNum = 0;
033:
034: protected BlockCipher createNewEngineForTest() {
035: return new AESEngine();
036: }
037:
038: private Test[] readTestVectors(InputStream inStream) {
039: // initialize key, plaintext, ciphertext = null
040: // read until find BLOCKSIZE=
041: // return if not 128
042: // read KEYSIZE= or ignore
043: // loop
044: // read a line
045: // if starts with BLOCKSIZE=
046: // parse the rest. return if not 128
047: // if starts with KEY=
048: // parse the rest and set KEY
049: // if starts with PT=
050: // parse the rest and set plaintext
051: // if starts with CT=
052: // parse the rest and set ciphertext
053: // if starts with TEST= or end of file
054: // if key, plaintext, ciphertext are all not null
055: // save away their values as the next test
056: // until end of file
057: List tests = new ArrayList();
058: String key = null;
059: String plaintext = null;
060: String ciphertext = null;
061:
062: BufferedReader in = new BufferedReader(new InputStreamReader(
063: inStream));
064:
065: try {
066: String line = in.readLine();
067:
068: while (line != null) {
069: line = line.trim().toLowerCase();
070: if (line.startsWith("blocksize=")) {
071: int i = 0;
072: try {
073: i = Integer.parseInt(line.substring(10).trim());
074: } catch (Exception e) {
075: }
076: if (i != 128) {
077: return null;
078: }
079: } else if (line.startsWith("keysize=")) {
080: int i = 0;
081: try {
082: i = Integer.parseInt(line.substring(10).trim());
083: } catch (Exception e) {
084: }
085: if ((i != 128) && (i != 192) && (i != 256)) {
086: return null;
087: }
088: } else if (line.startsWith("key=")) {
089: key = line.substring(4).trim();
090: } else if (line.startsWith("pt=")) {
091: plaintext = line.substring(3).trim();
092: } else if (line.startsWith("ct=")) {
093: ciphertext = line.substring(3).trim();
094: } else if (line.startsWith("test=")) {
095: if ((key != null) && (plaintext != null)
096: && (ciphertext != null)) {
097: tests.add(new BlockCipherVectorTest(testNum++,
098: createNewEngineForTest(),
099: new KeyParameter(Hex.decode(key)),
100: plaintext, ciphertext));
101: }
102: }
103:
104: line = in.readLine();
105: }
106: try {
107: in.close();
108: } catch (IOException e) {
109: }
110: } catch (IOException e) {
111: }
112: if ((key != null) && (plaintext != null)
113: && (ciphertext != null)) {
114: tests.add(new BlockCipherVectorTest(testNum++,
115: createNewEngineForTest(), new KeyParameter(Hex
116: .decode(key)), plaintext, ciphertext));
117: }
118: return (Test[]) (tests.toArray(new Test[tests.size()]));
119: }
120:
121: public String getName() {
122: return "AES";
123: }
124:
125: private TestResult performTestsFromZipFile(File zfile) {
126: try {
127: ZipFile inZip = new ZipFile(zfile);
128: for (Enumeration files = inZip.entries(); files
129: .hasMoreElements();) {
130: Test[] tests = null;
131: try {
132: tests = readTestVectors(inZip
133: .getInputStream((ZipEntry) (files
134: .nextElement())));
135: } catch (Exception e) {
136: return new SimpleTestResult(false, getName()
137: + ": threw " + e);
138: }
139: if (tests != null) {
140: for (int i = 0; i != tests.length; i++) {
141: TestResult res = tests[i].perform();
142: countOfTests++;
143:
144: if (!res.isSuccessful()) {
145: return res;
146: }
147: }
148: }
149: }
150: inZip.close();
151: return new SimpleTestResult(true, getName() + ": Okay");
152: } catch (Exception e) {
153: return new SimpleTestResult(false, getName() + ": threw "
154: + e);
155: }
156: }
157:
158: private static final String[] zipFileNames = { "rijn.tv.ecbnk.zip",
159: "rijn.tv.ecbnt.zip", "rijn.tv.ecbvk.zip",
160: "rijn.tv.ecbvt.zip" };
161:
162: public TestResult perform() {
163: countOfTests = 0;
164: for (int i = 0; i < zipFileNames.length; i++) {
165: File inf = new File(zipFileNames[i]);
166: TestResult res = performTestsFromZipFile(inf);
167: if (!res.isSuccessful()) {
168: return res;
169: }
170: }
171: return new SimpleTestResult(true, getName() + ": "
172: + countOfTests + " performed Okay");
173: }
174:
175: public static void main(String[] args) {
176: AESVectorFileTest test = new AESVectorFileTest();
177: TestResult result = test.perform();
178: System.out.println(result);
179:
180: test = new AESLightVectorFileTest();
181: result = test.perform();
182: System.out.println(result);
183:
184: test = new AESFastVectorFileTest();
185: result = test.perform();
186: System.out.println(result);
187:
188: }
189:
190: private static class AESLightVectorFileTest extends
191: AESVectorFileTest {
192: protected BlockCipher createNewEngineForTest() {
193: return new AESLightEngine();
194: }
195:
196: public String getName() {
197: return "AESLight";
198: }
199:
200: }
201:
202: private static class AESFastVectorFileTest extends
203: AESVectorFileTest {
204: protected BlockCipher createNewEngineForTest() {
205: return new AESFastEngine();
206: }
207:
208: public String getName() {
209: return "AESFast";
210: }
211:
212: }
213: }
|