001: package org.bouncycastle.jce.provider.test;
002:
003: import org.bouncycastle.jce.provider.BouncyCastleProvider;
004: import org.bouncycastle.util.encoders.Hex;
005: import org.bouncycastle.util.test.SimpleTest;
006:
007: import javax.crypto.Cipher;
008: import javax.crypto.CipherInputStream;
009: import javax.crypto.CipherOutputStream;
010: import javax.crypto.IllegalBlockSizeException;
011: import javax.crypto.KeyGenerator;
012: import javax.crypto.SecretKey;
013: import javax.crypto.SecretKeyFactory;
014: import javax.crypto.ShortBufferException;
015: import javax.crypto.spec.DESedeKeySpec;
016: import javax.crypto.spec.IvParameterSpec;
017: import javax.crypto.spec.RC2ParameterSpec;
018: import javax.crypto.spec.RC5ParameterSpec;
019: import javax.crypto.spec.SecretKeySpec;
020: import java.io.ByteArrayInputStream;
021: import java.io.ByteArrayOutputStream;
022: import java.io.DataInputStream;
023: import java.io.IOException;
024: import java.security.AlgorithmParameters;
025: import java.security.InvalidAlgorithmParameterException;
026: import java.security.InvalidKeyException;
027: import java.security.InvalidParameterException;
028: import java.security.Key;
029: import java.security.PrivateKey;
030: import java.security.PublicKey;
031: import java.security.SecureRandom;
032: import java.security.Security;
033: import java.security.spec.InvalidKeySpecException;
034: import java.security.spec.KeySpec;
035:
036: /**
037: * basic test class for a block cipher, basically this just exercises the provider, and makes sure we
038: * are behaving sensibly, correctness of the implementation is shown in the lightweight test classes.
039: */
040: public class BlockCipherTest extends SimpleTest {
041: static String[] cipherTests1 = {
042: "DES",
043: "466da00648ef0e1f9617b1f002e225251a3248d09172f46b9617b1f002e225250112ecb3da61bc99",
044: "DESede",
045: "2f4bc6b30c893fa549d82c560d61cf3eb088aed020603de249d82c560d61cf3e529e95ecd8e05394",
046: "SKIPJACK",
047: "d4de46d52274dbb029f33b076043f8c40089f906751623de29f33b076043f8c4ac99b90f9396cb04",
048: "Blowfish",
049: "25e15516062f0098e13ef22cab30289490a1db7887258a4fe13ef22cab302894b29698bcc4dd576e",
050: "Twofish",
051: "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c0839e31468661bcfc57a14899ceeb0253",
052: "RC2",
053: "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b994a5b859e765797",
054: "RC5",
055: "220053543e3eca3bc9503a091ca67b08372560d8a4fdbee8c9503a091ca67b08a796d53bb8a4b7e0",
056: "RC5-64",
057: "e0b4a526ba3bc5f09199c3b1fe3737fe6d248cde70e565b0feea59ebfda375ae1946c386a48d8d8a74d7b1947ff6a788",
058: "RC6",
059: "44c97b67ca8486067f8b6c5b97632f3049e5e52c1d61fdd527dc3da39616540f19a3db39aac1ffd713795cd886cce0c0",
060: "IDEA",
061: "8c9fd56823ffdc523f6ccf7f614aa6173553e594fc7a21b53f6ccf7f614aa61740c54f7a66e95108",
062: "TEA",
063: "fcf45062104fda7c35712368b56dd4216a6ca998dc297b5435712368b56dd421208027ed2923cd0c",
064: "XTEA",
065: "4b427893d3d6aaded2afafabe25f7b233fb5589faa2b6389d2afafabe25f7b239d12979ac67e1c07",
066: "Camellia",
067: "3a68b4ad145bc2c76010669d68f2826359887afce763a78d9994143266adfaec8ba7ee562a1688ef9dfd7f897e5c44dc",
068: "SEED",
069: "d53d4ce1f48b9879420949467bfcbfbe2c6a7d4a8770bee0c71211def898d7c5024ce2007dd85accb3f69d906ae2164d",
070: "Noekeon",
071: "7e68ceb33aad9db04af6b878a16dd6c6b4f880d6c89027ba581884c10690bb6b3dbfd6ed5513e2c4f5670c3528023121",
072: "DES/CBC/NoPadding",
073: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a",
074: "DESede/CBC/NoPadding",
075: "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231",
076: "SKIPJACK/CBC/NoPadding",
077: "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334",
078: "Blowfish/CBC/NoPadding",
079: "f12382107340125cd2f873db67d76b8a3ca0f83662e83bbca5af7f00080bdb49",
080: "Twofish/CBC/NoPadding",
081: "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a83812943",
082: "RC2/CBC/NoPadding",
083: "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf99",
084: "RC5/CBC/NoPadding",
085: "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3",
086: "RC6/CBC/NoPadding",
087: "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130",
088: "IDEA/CBC/NoPadding",
089: "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9",
090: "DES/CBC/PKCS5Padding",
091: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122afdc70484fb9c0232",
092: "DES/CBC/ISO10126Padding",
093: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8",
094: "DES/CBC/ISO7816-4Padding",
095: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a1f80b9b0f1be49ac",
096: "DES/CBC/X9.23Padding",
097: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122a980639850a2cc3e8",
098: "DESede/CBC/PKCS7Padding",
099: "4d3d7931875cf25593dc402298add8b914761e4936c9585ae22b2c1441169231a41e40695f1cff84",
100: "SKIPJACK/CBC/PKCS7Padding",
101: "ceebcc2e5e2b847f9ed797b4930b95f115b9e6cf49c457fc2ea0df79ad5c8334df7042de5db89c96",
102: "Blowfish/CBC/PKCS7Padding",
103: "f12382107340125cd2f873db67d76b8a3ca0f83662e83bbca5af7f00080bdb497968f18beabcc3aa",
104: "Twofish/CBC/PKCS7Padding",
105: "f819694251a00bdd403928745cd1d8a094de61f49ddf8e7692e9d81a838129433e5f1343d6cdb0b41838619da1541f04",
106: "RC2/CBC/PKCS7Padding",
107: "a51facdb3933c9676795cd38cc3146fd4694722b468b1a979a399c77606abf9958435525f770f137",
108: "RC5/CBC/PKCS7Padding",
109: "9ee7517eab0280445f3a7c60c90c0f75029d65bca8b1af83ace5399d388c83c3edd95ff49be76651",
110: "RC5-64/CBC/PKCS7Padding",
111: "e479fd11f89dab22d2f3dd062b1d2abd5b5962553421a5c562dc7214c3b23b8e21949fda87f2f820e5f032c552c6ec78",
112: "RC6/CBC/PKCS7Padding",
113: "c44695633c07010f3a0d8f7ea046a642d4a96bf4e44f89fd91b46830bc95b130824b972c9019a69d2dd05ef2d36b37ac",
114: "IDEA/CBC/PKCS7Padding",
115: "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32",
116: "IDEA/CBC/ISO10126Padding",
117: "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b",
118: "IDEA/CBC/X9.23Padding",
119: "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d978b3fd73135f033b",
120: "AES/CBC/PKCS7Padding",
121: "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7",
122: "AES/CBC/ISO7816-4Padding",
123: "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08306d84876508a33efec701118d8eeaf6d",
124: "Rijndael/CBC/PKCS7Padding",
125: "cf87f4d8bb9d1abb36cdd9f44ead7d046db2f802d99e1ef0a5940f306079e08389a44c4a8cc1a47cbaee1128da55bbb7",
126: "Serpent/CBC/PKCS7Padding",
127: "f8940ca31aba8ce1e0693b1ae0b1e08daef6de03c80f019774280052f824ac44540bb8dd74dfad47f83f9c7ec268ca68",
128: "CAST5/CBC/PKCS7Padding",
129: "87b6dc0c5a1d23d42fa740b0548be0b298112000544610d889d6361994cf8e670a19d6af72d7289f",
130: "CAST6/CBC/PKCS7Padding",
131: "943445569cfdda174118e433828f84e137faee38cac5c827d87a3c9a5a46a07dd64e7ad8accd921f248eea627cd6826f",
132: "DES/CBC/WithCTS",
133: "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12",
134: "IDEA/CBC/PKCS7Padding",
135: "30cd990ebdae80fe12b6c6e4fcd1c064a27d985c276b3d7097351c8684e4c4d9e584751325ef7c32",
136: "DES/CBC/ZeroBytePadding",
137: "60fa2f8fae5aa2a38e9ac77d0246726beb7511e4515feb12cf99f75cc6e0122ad3b3f002c927f1fd",
138: "DES/CTS/NoPadding", // official style
139: "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12",
140: "DESede/CTS/NoPadding",
141: "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a",
142: "SKIPJACK/CTS/NoPadding",
143: "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc",
144: "Blowfish/CTS/NoPadding",
145: "f12382107340125cd2f873db67d76b8aa5af7f00080bdb493ca0f83662e83bbc",
146: "Twofish/CTS/NoPadding",
147: "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0",
148: "AES/CTS/NoPadding",
149: "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04",
150: "Rijndael/CTS/NoPadding",
151: "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04",
152: "Serpent/CTS/NoPadding",
153: "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d",
154: "CAST5/CTS/NoPadding",
155: "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8",
156: "CAST6/CTS/NoPadding",
157: "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1",
158: "RC2/CTS/NoPadding",
159: "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97",
160: "RC5/CTS/NoPadding",
161: "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83",
162: "RC6/CTS/NoPadding",
163: "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642",
164: "IDEA/CTS/NoPadding",
165: "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70",
166: "DES/CBC/WithCTS", // older style
167: "60fa2f8fae5aa2a38e9ac77d0246726bcf99f75cc6e0122aeb7511e4515feb12",
168: "DESede/CBC/WithCTS",
169: "4d3d7931875cf25593dc402298add8b9e22b2c144116923114761e4936c9585a",
170: "SKIPJACK/CBC/WithCTS",
171: "ceebcc2e5e2b847f9ed797b4930b95f12ea0df79ad5c833415b9e6cf49c457fc",
172: "Blowfish/CBC/WithCTS",
173: "f12382107340125cd2f873db67d76b8aa5af7f00080bdb493ca0f83662e83bbc",
174: "Twofish/CBC/WithCTS",
175: "94de61f49ddf8e7692e9d81a83812943f819694251a00bdd403928745cd1d8a0",
176: "AES/CBC/WithCTS",
177: "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04",
178: "Rijndael/CBC/WithCTS",
179: "6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04",
180: "Serpent/CBC/WithCTS",
181: "aef6de03c80f019774280052f824ac44f8940ca31aba8ce1e0693b1ae0b1e08d",
182: "CAST5/CBC/WithCTS",
183: "87b6dc0c5a1d23d42fa740b0548be0b289d6361994cf8e6798112000544610d8",
184: "CAST6/CBC/WithCTS",
185: "37faee38cac5c827d87a3c9a5a46a07d943445569cfdda174118e433828f84e1",
186: "RC2/CBC/WithCTS",
187: "a51facdb3933c9676795cd38cc3146fd9a399c77606abf994694722b468b1a97",
188: "RC5/CBC/WithCTS",
189: "9ee7517eab0280445f3a7c60c90c0f75ace5399d388c83c3029d65bca8b1af83",
190: "RC6/CBC/WithCTS",
191: "d4a96bf4e44f89fd91b46830bc95b130c44695633c07010f3a0d8f7ea046a642",
192: "IDEA/CBC/WithCTS",
193: "30cd990ebdae80fe12b6c6e4fcd1c06497351c8684e4c4d9a27d985c276b3d70",
194: "DES/OFB/NoPadding",
195: "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e3f78b7",
196: "DESede/OFB/NoPadding",
197: "481e9872acea7fcf8e29a453242da774e5f6a28f15f7723659a73e4ff4939f80",
198: "SKIPJACK/OFB/NoPadding",
199: "71143a124e3a0cde753b60fe9b200e559018b6a0fe0682659f7c13feb9df995c",
200: "Blowfish/OFB/NoPadding",
201: "134bcde441a6dd1cde0a0cdfd325e6f2cceabfe2a810f4eeec8ddd51bc2e65ae",
202: "Twofish/OFB/NoPadding",
203: "821c54b1b54ae113cf74595eefe10c83b61c9682fc81f92c52f39a3a693f88b8",
204: "RC2/OFB/NoPadding",
205: "0a07cb78537cb04c0c74e28a7b86b80f80acadf87d6ef32792f1a8cf74b39f74",
206: "RC5/OFB/NoPadding",
207: "c62b233df296283b918a2b4cc53a54fbf061850e781b97332ed1bd78b88d9670",
208: "IDEA/OFB/NoPadding",
209: "dd447da3cbdcf81f4053fb446596261cb00a3c49a66085485af5f7c10ba20dad",
210: "DES/OFB8/NoPadding",
211: "53cb5010d189f94cf584e5ff1c4a9d86443c45ddb6fa3c2d1a5dadfcdf01db8a",
212: "DESede/OFB8/NoPadding",
213: "482c0c1ccd0e6d218e1cffb0a295352c2357ffaa673f2257ef5c77b6c04f03b5",
214: "SKIPJACK/OFB8/NoPadding",
215: "719ea1b432b3d2c8011e5aa873f95978420022b5e2c9c1a1c1082cd1f4999da2",
216: "Blowfish/OFB8/NoPadding",
217: "13a7e65359228380ae522b327734aaabf749f9b555cce4c531f9a31cd659f679",
218: "Twofish/OFB8/NoPadding",
219: "825dcec234ad52253d6e064b0d769bc04b1142435933f4a510ffc20d70095a88",
220: "RC2/OFB8/NoPadding",
221: "0aa26c6f6a820fe7d38da97085995ad62e2e293323a76300fcd4eb572810f7c6",
222: "RC5/OFB8/NoPadding",
223: "c601a9074dbd874f4d3293f6a32d93d9f0a4f5685d8597f0102fcc96d444f976",
224: "IDEA/OFB8/NoPadding",
225: "dd7897b6ced43d060a518bb38d570308b83b4de577eb208130daabf619e9b1fb",
226: "DES/CFB/NoPadding",
227: "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe747bb2",
228: "DESede/CFB/NoPadding",
229: "481e9872acea7fcfb75bb58670fe64c59123265139e357d161cd4ddb5eba042a",
230: "SKIPJACK/CFB/NoPadding",
231: "71143a124e3a0cde70a69ede4ceb14376b1e6a80bafde0a6330508dfa86a7c41",
232: "Blowfish/CFB/NoPadding",
233: "134bcde441a6dd1c0d7522225e94d4a5083a61326ea1f930fc28864296c2bf2c",
234: "Twofish/CFB/NoPadding",
235: "821c54b1b54ae113cf74595eefe10c8308b7a438277de4f40948ac2d172d53d2",
236: "RC2/CFB/NoPadding",
237: "0a07cb78537cb04ca1401450d5cd411c7da7fa5b6baaa17bb2137bd95c9f26a5",
238: "RC5/CFB/NoPadding",
239: "c62b233df296283b989352bbebf616a19e11503ac737f9e0eaf19049cde05d34",
240: "IDEA/CFB/NoPadding",
241: "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a",
242: "DES/CFB8/NoPadding",
243: "53cb0cdff712a825eb283b23c31e7323aa12495e7e751428b5c4eb89b28a25d4",
244: "DESede/CFB8/NoPadding",
245: "482cd5bf87ca4cee0b573d66a077231bfea93843ce2d1f948550a1d208e18279",
246: "SKIPJACK/CFB8/NoPadding",
247: "719eef3906bef23f7b63599285437d8e34183b165acf3e855b4e160d4f036508",
248: "Blowfish/CFB8/NoPadding",
249: "13a7674626f78b0ed58c4e55f9f5d90b97dd7926533ac8840af8c7c1a7ca8dd8",
250: "Twofish/CFB8/NoPadding",
251: "825d12af040721cf5ed4a4798647837ac5eb14d752aace28728aeb37b2010abd",
252: "RC2/CFB8/NoPadding",
253: "0aa227f94be3a32ff927c5d25647ea41d7c2a1e94012fc7f2ad6767b9664bce5",
254: "RC5/CFB8/NoPadding",
255: "c601cf88725411f119965b9cd38d6c313b91128ed7c98c7604cc62d9b210be79",
256: "IDEA/CFB8/NoPadding",
257: "dd7839d2525420d10f95eec23dbaf3463302c445972a28c563c2635191bc19af",
258: "IDEA/PGPCFB/NoPadding",
259: "dd447da3cbdcf81fcbe4661dcbed88aed899f87585118384bd0565067fa6c13a",
260: "IDEA/PGPCFBwithIv/NoPadding",
261: "ed5adbac0e730cc0f00df7e4f6fef672ab042673106435faf3ecf3996a72a0e127b440ba9e5313501de3",
262: "Twofish/ECB/TBCPadding",
263: "70336d9c9718a8a2ced1b19deed973a3c58af7ea71a69e7efc4df082dca581c019d7daa58d02b89aab6e8c0d17202439",
264: "RC2/ECB/TBCPadding",
265: "eb5b889bbcced12eb6b1a3da6a3d965bba66a5edfdd4c8a6b6b1a3da6a3d965b6b5359ba5e69b179" };
266:
267: static String[] cipherTests2 = {
268: "DES/OFB64/NoPadding",
269: "537572e480c1714f5c9a4f3b874df824dc6681b1fd6c11982debcad91e",
270: "DES/CFB64/NoPadding",
271: "537572e480c1714fec3c7424f88d4202219244c5ca8f5e4361d64f08fe",
272: "DES/CTR/NoPadding",
273: "537572e480c1714fb47081d35eb18eaca9e0a5aee982f105438a0db6ce",
274: "DES/CTS/NoPadding",
275: "60fa2f8fae5aa2a38e9ac77d0246726b32df660db51a710ceb7511e451" };
276:
277: static byte[] input1 = Hex
278: .decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f");
279: static byte[] input2 = Hex
280: .decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c");
281:
282: static RC2ParameterSpec rc2Spec = new RC2ParameterSpec(128, Hex
283: .decode("0123456789abcdef"));
284: static RC5ParameterSpec rc5Spec = new RC5ParameterSpec(16, 16, 32,
285: Hex.decode("0123456789abcdef"));
286: static RC5ParameterSpec rc564Spec = new RC5ParameterSpec(16, 16,
287: 64, Hex.decode("0123456789abcdef0123456789abcdef"));
288:
289: /**
290: * a fake random number generator - we just want to make sure the random numbers
291: * aren't random so that we get the same output, while still getting to test the
292: * key generation facilities.
293: */
294: private class FixedSecureRandom extends SecureRandom {
295: byte[] seed = { (byte) 0xaa, (byte) 0xfd, (byte) 0x12,
296: (byte) 0xf6, (byte) 0x59, (byte) 0xca, (byte) 0xe6,
297: (byte) 0x34, (byte) 0x89, (byte) 0xb4, (byte) 0x79,
298: (byte) 0xe5, (byte) 0x07, (byte) 0x6d, (byte) 0xde,
299: (byte) 0xc2, (byte) 0xf0, (byte) 0x6c, (byte) 0xb5,
300: (byte) 0x8f };
301:
302: public void nextBytes(byte[] bytes) {
303: int offset = 0;
304:
305: while ((offset + seed.length) < bytes.length) {
306: System.arraycopy(seed, 0, bytes, offset, seed.length);
307: offset += seed.length;
308: }
309:
310: System.arraycopy(seed, 0, bytes, offset, bytes.length
311: - offset);
312: }
313: }
314:
315: public String getName() {
316: return "BlockCipher";
317: }
318:
319: public void test(String algorithm, byte[] input, byte[] output) {
320: Key key = null;
321: KeyGenerator keyGen;
322: SecureRandom rand;
323: Cipher in = null;
324: Cipher out = null;
325: CipherInputStream cIn;
326: CipherOutputStream cOut;
327: ByteArrayInputStream bIn;
328: ByteArrayOutputStream bOut;
329:
330: rand = new FixedSecureRandom();
331:
332: try {
333: String baseAlgorithm;
334: int index = algorithm.indexOf('/');
335:
336: if (index > 0) {
337: baseAlgorithm = algorithm.substring(0, index);
338: } else {
339: baseAlgorithm = algorithm;
340: }
341:
342: keyGen = KeyGenerator.getInstance(baseAlgorithm, "BC");
343: if (!keyGen.getAlgorithm().equals(baseAlgorithm)) {
344: fail("wrong key generator returned!");
345: }
346: keyGen.init(rand);
347:
348: key = keyGen.generateKey();
349:
350: in = Cipher.getInstance(algorithm, "BC");
351: out = Cipher.getInstance(algorithm, "BC");
352:
353: if (!in.getAlgorithm().startsWith(baseAlgorithm)) {
354: fail("wrong cipher returned!");
355: }
356:
357: if (algorithm.startsWith("RC2")) {
358: out.init(Cipher.ENCRYPT_MODE, key, rc2Spec, rand);
359: } else if (algorithm.startsWith("RC5")) {
360: if (algorithm.startsWith("RC5-64")) {
361: out.init(Cipher.ENCRYPT_MODE, key, rc564Spec, rand);
362: } else {
363: out.init(Cipher.ENCRYPT_MODE, key, rc5Spec, rand);
364: }
365: } else {
366: out.init(Cipher.ENCRYPT_MODE, key, rand);
367: }
368: } catch (Exception e) {
369: fail("" + algorithm + " failed initialisation - "
370: + e.toString(), e);
371: }
372:
373: //
374: // grab the iv if there is one
375: //
376: try {
377: if (algorithm.startsWith("RC2")) {
378: in.init(Cipher.DECRYPT_MODE, key, rc2Spec);
379: } else if (algorithm.startsWith("RC5")) {
380: if (algorithm.startsWith("RC5-64")) {
381: in.init(Cipher.DECRYPT_MODE, key, rc564Spec, rand);
382: } else {
383: in.init(Cipher.DECRYPT_MODE, key, rc5Spec, rand);
384: }
385: } else {
386: byte[] iv;
387:
388: iv = out.getIV();
389: if (iv != null) {
390: try {
391: byte[] nIv = new byte[iv.length - 1];
392:
393: in.init(Cipher.DECRYPT_MODE, key,
394: new IvParameterSpec(nIv));
395: fail("failed to pick up short IV");
396: } catch (InvalidAlgorithmParameterException e) {
397: // ignore - this is what we want...
398: }
399:
400: IvParameterSpec spec;
401:
402: spec = new IvParameterSpec(iv);
403:
404: in.init(Cipher.DECRYPT_MODE, key, spec);
405: } else {
406: in.init(Cipher.DECRYPT_MODE, key);
407: }
408: }
409: } catch (Exception e) {
410: fail("" + algorithm + " failed initialisation - "
411: + e.toString());
412: }
413:
414: //
415: // encryption pass
416: //
417: bOut = new ByteArrayOutputStream();
418:
419: cOut = new CipherOutputStream(bOut, out);
420:
421: try {
422: for (int i = 0; i != input.length / 2; i++) {
423: cOut.write(input[i]);
424: }
425: cOut.write(input, input.length / 2, input.length
426: - input.length / 2);
427: cOut.close();
428: } catch (IOException e) {
429: fail("" + algorithm + " failed encryption - "
430: + e.toString());
431: }
432:
433: byte[] bytes;
434:
435: bytes = bOut.toByteArray();
436:
437: if (!areEqual(bytes, output)) {
438: fail("" + algorithm + " failed encryption - expected "
439: + new String(Hex.encode(output)) + " got "
440: + new String(Hex.encode(bytes)));
441: }
442:
443: //
444: // decryption pass
445: //
446: bIn = new ByteArrayInputStream(bytes);
447:
448: cIn = new CipherInputStream(bIn, in);
449:
450: try {
451: DataInputStream dIn = new DataInputStream(cIn);
452:
453: bytes = new byte[input.length];
454:
455: for (int i = 0; i != input.length / 2; i++) {
456: bytes[i] = (byte) dIn.read();
457: }
458: dIn.readFully(bytes, input.length / 2, bytes.length
459: - input.length / 2);
460: } catch (Exception e) {
461: fail("" + algorithm + " failed decryption - "
462: + e.toString());
463: }
464:
465: if (!areEqual(bytes, input)) {
466: fail("" + algorithm + " failed decryption - expected "
467: + new String(Hex.encode(input)) + " got "
468: + new String(Hex.encode(bytes)));
469: }
470: }
471:
472: private void testExceptions() {
473: SecretKeyFactory skF = null;
474:
475: try {
476: skF = SecretKeyFactory.getInstance("DESede", "BC");
477: } catch (Exception e) {
478: fail("unexpected exception.", e);
479: }
480:
481: KeySpec ks = null;
482: SecretKey secKey = null;
483: byte[] bb = new byte[24];
484:
485: try {
486: skF.getKeySpec(null, null);
487:
488: fail("failed exception test - no exception thrown");
489: } catch (InvalidKeySpecException e) {
490: // ignore okay
491: } catch (Exception e) {
492: fail("failed exception test.", e);
493: }
494: try {
495: ks = (KeySpec) new DESedeKeySpec(bb);
496: skF.getKeySpec(null, ks.getClass());
497:
498: fail("failed exception test - no exception thrown");
499: } catch (InvalidKeySpecException e) {
500: // ignore okay;
501: } catch (Exception e) {
502: fail("failed exception test.", e);
503: }
504: try {
505: skF.getKeySpec(secKey, null);
506: } catch (InvalidKeySpecException e) {
507: // ignore okay
508: } catch (Exception e) {
509: fail("failed exception test.", e);
510: }
511:
512: try {
513: KeyGenerator kg = KeyGenerator.getInstance("DESede", "BC");
514: try {
515: kg.init(Integer.MIN_VALUE, new SecureRandom());
516:
517: fail("failed exception test - no exception thrown");
518: } catch (InvalidParameterException e) {
519: // ignore okay
520: } catch (Exception e) {
521: fail("failed exception test.", e);
522: }
523: } catch (Exception e) {
524: fail("unexpected exception.", e);
525: }
526:
527: try {
528: skF = SecretKeyFactory.getInstance("DESede", "BC");
529:
530: try {
531: skF.translateKey(null);
532:
533: fail("failed exception test - no exception thrown");
534: } catch (InvalidKeyException e) {
535: // ignore okay
536: } catch (Exception e) {
537: fail("failed exception test.", e);
538: }
539: } catch (Exception e) {
540: fail("unexpected exception.", e);
541: }
542:
543: try {
544: byte[] rawDESKey = { (byte) 128, (byte) 131, (byte) 133,
545: (byte) 134, (byte) 137, (byte) 138, (byte) 140,
546: (byte) 143 };
547:
548: SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey,
549: "DES");
550:
551: Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding",
552: "BC");
553:
554: try {
555: // According specification engineInit(int opmode, Key key,
556: // SecureRandom random) throws InvalidKeyException if this
557: // cipher is being
558: // initialized for decryption and requires algorithm parameters
559: // that cannot be determined from the given key
560: cipher.init(Cipher.DECRYPT_MODE, cipherKey,
561: (SecureRandom) null);
562:
563: fail("failed exception test - no InvalidKeyException thrown");
564: } catch (InvalidKeyException e) {
565: // ignore
566: }
567: } catch (Exception e) {
568: fail("unexpected exception.", e);
569: }
570:
571: try {
572: byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 };
573:
574: SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey,
575: "DES");
576: Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding",
577: "BC");
578: try {
579: // According specification engineInit(int opmode, Key key,
580: // SecureRandom random) throws InvalidKeyException if the given
581: // key is inappropriate for initializing this cipher
582: cipher.init(Cipher.ENCRYPT_MODE, cipherKey);
583:
584: fail("failed exception test - no InvalidKeyException thrown");
585: } catch (InvalidKeyException e) {
586: // ignore
587: }
588: } catch (Exception e) {
589: fail("unexpected exception.", e);
590: }
591:
592: try {
593: byte[] rawDESKey = { -128, -125, -123, -122, -119, -118,
594: -117, -115, -114 };
595:
596: SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey,
597: "DES");
598: Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding",
599: "BC");
600: try {
601: // According specification engineInit(int opmode, Key key,
602: // SecureRandom random) throws InvalidKeyException if the given
603: // key is inappropriate for initializing this cipher
604: cipher.init(Cipher.ENCRYPT_MODE, cipherKey);
605:
606: fail("failed exception test - no InvalidKeyException thrown");
607: } catch (InvalidKeyException e) {
608: // ignore
609: }
610: } catch (Exception e) {
611: fail("unexpected exception.", e);
612: }
613:
614: try {
615: byte[] rawDESKey = { (byte) 128, (byte) 131, (byte) 133,
616: (byte) 134, (byte) 137, (byte) 138, (byte) 140,
617: (byte) 143 };
618:
619: SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey,
620: "DES");
621: Cipher ecipher = Cipher.getInstance("DES/ECB/PKCS5Padding",
622: "BC");
623: ecipher.init(Cipher.ENCRYPT_MODE, cipherKey);
624:
625: byte[] cipherText = new byte[0];
626: try {
627: // According specification Method engineUpdate(byte[] input,
628: // int inputOffset, int inputLen, byte[] output, int
629: // outputOffset)
630: // throws ShortBufferException - if the given output buffer is
631: // too
632: // small to hold the result
633: ecipher.update(new byte[20], 0, 20, cipherText);
634:
635: fail("failed exception test - no ShortBufferException thrown");
636: } catch (ShortBufferException e) {
637: // ignore
638: }
639: } catch (Exception e) {
640: fail("unexpected exception.", e);
641: }
642:
643: try {
644: KeyGenerator keyGen = KeyGenerator.getInstance("DES", "BC");
645:
646: keyGen.init((SecureRandom) null);
647:
648: // According specification engineGenerateKey() doesn't throw any exceptions.
649:
650: SecretKey key = keyGen.generateKey();
651: if (key == null) {
652: fail("key is null!");
653: }
654: } catch (Exception e) {
655: fail("unexpected exception.", e);
656: }
657:
658: try {
659: AlgorithmParameters algParams = AlgorithmParameters
660: .getInstance("DES", "BC");
661:
662: algParams.init(new IvParameterSpec(new byte[8]));
663:
664: // According specification engineGetEncoded() returns
665: // the parameters in their primary encoding format. The primary
666: // encoding
667: // format for parameters is ASN.1, if an ASN.1 specification for
668: // this type
669: // of parameters exists.
670: byte[] iv = algParams.getEncoded();
671:
672: if (iv.length != 10) {
673: fail("parameters encoding wrong length - " + iv.length);
674: }
675: } catch (Exception e) {
676: fail("unexpected exception.", e);
677: }
678:
679: try {
680: try {
681: AlgorithmParameters algParams = AlgorithmParameters
682: .getInstance("DES", "BC");
683:
684: byte[] encoding = new byte[10];
685: encoding[0] = 3;
686: encoding[1] = 8;
687:
688: // According specification engineInit(byte[] params, String format)
689: // throws
690: // IOException on decoding errors, but BC throws ClassCastException.
691: algParams.init(encoding, "ASN.1");
692:
693: fail("failed exception test - no IOException thrown");
694: } catch (IOException e) {
695: // okay
696: }
697:
698: try {
699: Cipher c = Cipher.getInstance("DES", "BC");
700:
701: Key k = new PublicKey() {
702:
703: public String getAlgorithm() {
704: return "STUB";
705: }
706:
707: public String getFormat() {
708: return null;
709: }
710:
711: public byte[] getEncoded() {
712: return null;
713: }
714:
715: };
716:
717: c.init(Cipher.ENCRYPT_MODE, k);
718:
719: fail("failed exception test - no InvalidKeyException thrown for public key");
720: } catch (InvalidKeyException e) {
721: // okay
722: }
723:
724: try {
725: Cipher c = Cipher.getInstance("DES", "BC");
726:
727: Key k = new PrivateKey() {
728:
729: public String getAlgorithm() {
730: return "STUB";
731: }
732:
733: public String getFormat() {
734: return null;
735: }
736:
737: public byte[] getEncoded() {
738: return null;
739: }
740:
741: };
742:
743: c.init(Cipher.DECRYPT_MODE, k);
744:
745: fail("failed exception test - no InvalidKeyException thrown for private key");
746: } catch (InvalidKeyException e) {
747: // okay
748: }
749: } catch (Exception e) {
750: fail("unexpected exception.", e);
751: }
752: }
753:
754: public void performTest() {
755: for (int i = 0; i != cipherTests1.length; i += 2) {
756: test(cipherTests1[i], input1, Hex
757: .decode(cipherTests1[i + 1]));
758: }
759:
760: for (int i = 0; i != cipherTests2.length; i += 2) {
761: test(cipherTests2[i], input2, Hex
762: .decode(cipherTests2[i + 1]));
763: }
764:
765: //
766: // check for less than a block
767: //
768: try {
769: Cipher c = Cipher.getInstance("AES/CTS/NoPadding", "BC");
770:
771: c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16],
772: "AES"));
773:
774: c.doFinal(new byte[4]);
775:
776: fail("CTS failed to throw exception");
777: } catch (Exception e) {
778: if (!(e instanceof IllegalBlockSizeException)) {
779: fail("CTS exception test - " + e, e);
780: }
781: }
782:
783: testExceptions();
784: }
785:
786: public static void main(String[] args) {
787: Security.addProvider(new BouncyCastleProvider());
788:
789: runTest(new BlockCipherTest());
790: }
791: }
|