PageRenderTime 71ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/src/org/bouncycastle/jce/provider/JCEBlockCipher.java

https://github.com/kllrnohj/keepassdroid
Java | 1405 lines | 563 code | 112 blank | 730 comment | 88 complexity | 6054fcecb0971e6875c5f34c8deb4a5f MD5 | raw file
  1. package org.bouncycastle.jce.provider;
  2. import org.bouncycastle.crypto.BlockCipher;
  3. import org.bouncycastle.crypto.BufferedBlockCipher;
  4. import org.bouncycastle.crypto.CipherParameters;
  5. import org.bouncycastle.crypto.DataLengthException;
  6. import org.bouncycastle.crypto.InvalidCipherTextException;
  7. /*
  8. import org.bouncycastle.crypto.engines.AESFastEngine;
  9. import org.bouncycastle.crypto.engines.BlowfishEngine;
  10. import org.bouncycastle.crypto.engines.CAST5Engine;
  11. import org.bouncycastle.crypto.engines.CAST6Engine;
  12. import org.bouncycastle.crypto.engines.DESEngine;
  13. import org.bouncycastle.crypto.engines.DESedeEngine;
  14. import org.bouncycastle.crypto.engines.GOST28147Engine;
  15. import org.bouncycastle.crypto.engines.RC2Engine;
  16. import org.bouncycastle.crypto.engines.RC532Engine;
  17. import org.bouncycastle.crypto.engines.RC564Engine;
  18. import org.bouncycastle.crypto.engines.RC6Engine;
  19. import org.bouncycastle.crypto.engines.RijndaelEngine;
  20. import org.bouncycastle.crypto.engines.SEEDEngine;
  21. import org.bouncycastle.crypto.engines.SerpentEngine;
  22. import org.bouncycastle.crypto.engines.SkipjackEngine;
  23. import org.bouncycastle.crypto.engines.TEAEngine;
  24. */
  25. import org.bouncycastle.crypto.engines.TwofishEngine;
  26. //import org.bouncycastle.crypto.engines.XTEAEngine;
  27. //import org.bouncycastle.crypto.modes.AEADBlockCipher;
  28. import org.bouncycastle.crypto.modes.CBCBlockCipher;
  29. //import org.bouncycastle.crypto.modes.CCMBlockCipher;
  30. import org.bouncycastle.crypto.modes.CFBBlockCipher;
  31. import org.bouncycastle.crypto.modes.CTSBlockCipher;
  32. /*
  33. import org.bouncycastle.crypto.modes.EAXBlockCipher;
  34. import org.bouncycastle.crypto.modes.GCMBlockCipher;
  35. import org.bouncycastle.crypto.modes.GOFBBlockCipher;
  36. */
  37. import org.bouncycastle.crypto.modes.OFBBlockCipher;
  38. /*
  39. import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
  40. import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
  41. import org.bouncycastle.crypto.modes.SICBlockCipher;
  42. import org.bouncycastle.crypto.paddings.BlockCipherPadding;
  43. import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
  44. import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
  45. */
  46. import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
  47. /*
  48. import org.bouncycastle.crypto.paddings.TBCPadding;
  49. import org.bouncycastle.crypto.paddings.X923Padding;
  50. import org.bouncycastle.crypto.paddings.ZeroBytePadding;
  51. */
  52. import org.bouncycastle.crypto.params.KeyParameter;
  53. import org.bouncycastle.crypto.params.ParametersWithIV;
  54. import org.bouncycastle.crypto.params.ParametersWithRandom;
  55. /*
  56. import org.bouncycastle.crypto.params.ParametersWithSBox;
  57. import org.bouncycastle.crypto.params.RC2Parameters;
  58. import org.bouncycastle.crypto.params.RC5Parameters;
  59. import org.bouncycastle.jce.spec.GOST28147ParameterSpec;
  60. */
  61. import org.bouncycastle.util.Strings;
  62. import javax.crypto.BadPaddingException;
  63. import javax.crypto.Cipher;
  64. import javax.crypto.IllegalBlockSizeException;
  65. import javax.crypto.NoSuchPaddingException;
  66. import javax.crypto.SecretKey;
  67. import javax.crypto.ShortBufferException;
  68. import javax.crypto.spec.IvParameterSpec;
  69. import javax.crypto.spec.PBEParameterSpec;
  70. /*
  71. import javax.crypto.spec.RC2ParameterSpec;
  72. import javax.crypto.spec.RC5ParameterSpec;
  73. */
  74. import java.security.AlgorithmParameters;
  75. import java.security.InvalidAlgorithmParameterException;
  76. import java.security.InvalidKeyException;
  77. import java.security.InvalidParameterException;
  78. import java.security.Key;
  79. import java.security.NoSuchAlgorithmException;
  80. import java.security.SecureRandom;
  81. import java.security.spec.AlgorithmParameterSpec;
  82. @SuppressWarnings("unchecked")
  83. public class JCEBlockCipher extends WrapCipherSpi
  84. implements PBE
  85. {
  86. //
  87. // specs we can handle.
  88. //
  89. private Class[] availableSpecs =
  90. {
  91. //RC2ParameterSpec.class,
  92. //RC5ParameterSpec.class,
  93. IvParameterSpec.class,
  94. PBEParameterSpec.class,
  95. //GOST28147ParameterSpec.class
  96. };
  97. private BlockCipher baseEngine;
  98. private GenericBlockCipher cipher;
  99. private ParametersWithIV ivParam;
  100. private int ivLength = 0;
  101. private boolean padded;
  102. private PBEParameterSpec pbeSpec = null;
  103. private String pbeAlgorithm = null;
  104. private String modeName = null;
  105. protected JCEBlockCipher(
  106. BlockCipher engine)
  107. {
  108. baseEngine = engine;
  109. cipher = new BufferedGenericBlockCipher(engine);
  110. }
  111. protected JCEBlockCipher(
  112. BlockCipher engine,
  113. int ivLength)
  114. {
  115. baseEngine = engine;
  116. this.cipher = new BufferedGenericBlockCipher(engine);
  117. this.ivLength = ivLength / 8;
  118. }
  119. protected JCEBlockCipher(
  120. BufferedBlockCipher engine,
  121. int ivLength)
  122. {
  123. baseEngine = engine.getUnderlyingCipher();
  124. this.cipher = new BufferedGenericBlockCipher(engine);
  125. this.ivLength = ivLength / 8;
  126. }
  127. protected int engineGetBlockSize()
  128. {
  129. return baseEngine.getBlockSize();
  130. }
  131. protected byte[] engineGetIV()
  132. {
  133. return (ivParam != null) ? ivParam.getIV() : null;
  134. }
  135. protected int engineGetKeySize(
  136. Key key)
  137. {
  138. return key.getEncoded().length * 8;
  139. }
  140. protected int engineGetOutputSize(
  141. int inputLen)
  142. {
  143. return cipher.getOutputSize(inputLen);
  144. }
  145. protected AlgorithmParameters engineGetParameters()
  146. {
  147. if (engineParams == null)
  148. {
  149. if (pbeSpec != null)
  150. {
  151. try
  152. {
  153. engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, "BC");
  154. engineParams.init(pbeSpec);
  155. }
  156. catch (Exception e)
  157. {
  158. return null;
  159. }
  160. }
  161. else if (ivParam != null)
  162. {
  163. String name = cipher.getUnderlyingCipher().getAlgorithmName();
  164. if (name.indexOf('/') >= 0)
  165. {
  166. name = name.substring(0, name.indexOf('/'));
  167. }
  168. try
  169. {
  170. engineParams = AlgorithmParameters.getInstance(name, "BC");
  171. engineParams.init(ivParam.getIV());
  172. }
  173. catch (Exception e)
  174. {
  175. throw new RuntimeException(e.toString());
  176. }
  177. }
  178. }
  179. return engineParams;
  180. }
  181. protected void engineSetMode(
  182. String mode)
  183. throws NoSuchAlgorithmException
  184. {
  185. modeName = Strings.toUpperCase(mode);
  186. if (modeName.equals("ECB"))
  187. {
  188. ivLength = 0;
  189. cipher = new BufferedGenericBlockCipher(baseEngine);
  190. }
  191. else if (modeName.equals("CBC"))
  192. {
  193. ivLength = baseEngine.getBlockSize();
  194. cipher = new BufferedGenericBlockCipher(
  195. new CBCBlockCipher(baseEngine));
  196. }
  197. else if (modeName.startsWith("OFB"))
  198. {
  199. ivLength = baseEngine.getBlockSize();
  200. if (modeName.length() != 3)
  201. {
  202. int wordSize = Integer.parseInt(modeName.substring(3));
  203. cipher = new BufferedGenericBlockCipher(
  204. new OFBBlockCipher(baseEngine, wordSize));
  205. }
  206. else
  207. {
  208. cipher = new BufferedGenericBlockCipher(
  209. new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
  210. }
  211. }
  212. else if (modeName.startsWith("CFB"))
  213. {
  214. ivLength = baseEngine.getBlockSize();
  215. if (modeName.length() != 3)
  216. {
  217. int wordSize = Integer.parseInt(modeName.substring(3));
  218. cipher = new BufferedGenericBlockCipher(
  219. new CFBBlockCipher(baseEngine, wordSize));
  220. }
  221. else
  222. {
  223. cipher = new BufferedGenericBlockCipher(
  224. new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
  225. }
  226. }
  227. /*
  228. else if (modeName.startsWith("PGP"))
  229. {
  230. boolean inlineIV = modeName.equalsIgnoreCase("PGPCFBwithIV");
  231. ivLength = baseEngine.getBlockSize();
  232. cipher = new BufferedGenericBlockCipher(
  233. new PGPCFBBlockCipher(baseEngine, inlineIV));
  234. }
  235. else if (modeName.equalsIgnoreCase("OpenPGPCFB"))
  236. {
  237. ivLength = 0;
  238. cipher = new BufferedGenericBlockCipher(
  239. new OpenPGPCFBBlockCipher(baseEngine));
  240. }
  241. else if (modeName.startsWith("SIC"))
  242. {
  243. ivLength = baseEngine.getBlockSize();
  244. if (ivLength < 16)
  245. {
  246. throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
  247. }
  248. cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
  249. new SICBlockCipher(baseEngine)));
  250. }
  251. else if (modeName.startsWith("CTR"))
  252. {
  253. ivLength = baseEngine.getBlockSize();
  254. cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
  255. new SICBlockCipher(baseEngine)));
  256. }
  257. else if (modeName.startsWith("GOFB"))
  258. {
  259. ivLength = baseEngine.getBlockSize();
  260. cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
  261. new GOFBBlockCipher(baseEngine)));
  262. }
  263. else if (modeName.startsWith("CTS"))
  264. {
  265. ivLength = baseEngine.getBlockSize();
  266. cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine)));
  267. }
  268. else if (modeName.startsWith("CCM"))
  269. {
  270. ivLength = baseEngine.getBlockSize();
  271. cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
  272. }
  273. else if (modeName.startsWith("EAX"))
  274. {
  275. ivLength = baseEngine.getBlockSize();
  276. cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine));
  277. }
  278. else if (modeName.startsWith("GCM"))
  279. {
  280. ivLength = baseEngine.getBlockSize();
  281. cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
  282. }
  283. */
  284. else
  285. {
  286. throw new NoSuchAlgorithmException("can't support mode " + mode);
  287. }
  288. }
  289. protected void engineSetPadding(
  290. String padding)
  291. throws NoSuchPaddingException
  292. {
  293. String paddingName = Strings.toUpperCase(padding);
  294. if (paddingName.equals("NOPADDING"))
  295. {
  296. if (cipher.wrapOnNoPadding())
  297. {
  298. cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher()));
  299. }
  300. }
  301. else if (paddingName.equals("WITHCTS"))
  302. {
  303. cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(cipher.getUnderlyingCipher()));
  304. }
  305. else
  306. {
  307. padded = true;
  308. if (isAEADModeName(modeName))
  309. {
  310. throw new NoSuchPaddingException("Only NoPadding can be used with AEAD modes.");
  311. }
  312. else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING"))
  313. {
  314. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher());
  315. }
  316. /*
  317. else if (paddingName.equals("ZEROBYTEPADDING"))
  318. {
  319. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ZeroBytePadding());
  320. }
  321. else if (paddingName.equals("ISO10126PADDING") || paddingName.equals("ISO10126-2PADDING"))
  322. {
  323. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO10126d2Padding());
  324. }
  325. else if (paddingName.equals("X9.23PADDING") || paddingName.equals("X923PADDING"))
  326. {
  327. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new X923Padding());
  328. }
  329. else if (paddingName.equals("ISO7816-4PADDING") || paddingName.equals("ISO9797-1PADDING"))
  330. {
  331. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO7816d4Padding());
  332. }
  333. else if (paddingName.equals("TBCPADDING"))
  334. {
  335. cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new TBCPadding());
  336. }
  337. */
  338. else
  339. {
  340. throw new NoSuchPaddingException("Padding " + padding + " unknown.");
  341. }
  342. }
  343. }
  344. protected void engineInit(
  345. int opmode,
  346. Key key,
  347. AlgorithmParameterSpec params,
  348. SecureRandom random)
  349. throws InvalidKeyException, InvalidAlgorithmParameterException
  350. {
  351. CipherParameters param;
  352. this.pbeSpec = null;
  353. this.pbeAlgorithm = null;
  354. this.engineParams = null;
  355. //
  356. // basic key check
  357. //
  358. if (!(key instanceof SecretKey))
  359. {
  360. throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
  361. }
  362. //
  363. // for RC5-64 we must have some default parameters
  364. //
  365. if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64"))
  366. {
  367. throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in.");
  368. }
  369. //
  370. // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
  371. //
  372. if (key instanceof JCEPBEKey)
  373. {
  374. JCEPBEKey k = (JCEPBEKey)key;
  375. if (k.getOID() != null)
  376. {
  377. pbeAlgorithm = k.getOID().getId();
  378. }
  379. else
  380. {
  381. pbeAlgorithm = k.getAlgorithm();
  382. }
  383. if (k.getParam() != null)
  384. {
  385. param = k.getParam();
  386. pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
  387. }
  388. else if (params instanceof PBEParameterSpec)
  389. {
  390. pbeSpec = (PBEParameterSpec)params;
  391. param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName());
  392. }
  393. else
  394. {
  395. throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
  396. }
  397. if (param instanceof ParametersWithIV)
  398. {
  399. ivParam = (ParametersWithIV)param;
  400. }
  401. }
  402. else if (params == null)
  403. {
  404. param = new KeyParameter(key.getEncoded());
  405. }
  406. else if (params instanceof IvParameterSpec)
  407. {
  408. if (ivLength != 0)
  409. {
  410. IvParameterSpec p = (IvParameterSpec)params;
  411. if (p.getIV().length != ivLength && !isAEADModeName(modeName))
  412. {
  413. throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long.");
  414. }
  415. param = new ParametersWithIV(new KeyParameter(key.getEncoded()), p.getIV());
  416. ivParam = (ParametersWithIV)param;
  417. }
  418. else
  419. {
  420. if (modeName != null && modeName.equals("ECB"))
  421. {
  422. throw new InvalidAlgorithmParameterException("ECB mode does not use an IV");
  423. }
  424. param = new KeyParameter(key.getEncoded());
  425. }
  426. }
  427. /*
  428. else if (params instanceof GOST28147ParameterSpec)
  429. {
  430. GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
  431. param = new ParametersWithSBox(
  432. new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
  433. if (gost28147Param.getIV() != null && ivLength != 0)
  434. {
  435. param = new ParametersWithIV(param, gost28147Param.getIV());
  436. ivParam = (ParametersWithIV)param;
  437. }
  438. }
  439. else if (params instanceof RC2ParameterSpec)
  440. {
  441. RC2ParameterSpec rc2Param = (RC2ParameterSpec)params;
  442. param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits());
  443. if (rc2Param.getIV() != null && ivLength != 0)
  444. {
  445. param = new ParametersWithIV(param, rc2Param.getIV());
  446. ivParam = (ParametersWithIV)param;
  447. }
  448. }
  449. else if (params instanceof RC5ParameterSpec)
  450. {
  451. RC5ParameterSpec rc5Param = (RC5ParameterSpec)params;
  452. param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds());
  453. if (baseEngine.getAlgorithmName().startsWith("RC5"))
  454. {
  455. if (baseEngine.getAlgorithmName().equals("RC5-32"))
  456. {
  457. if (rc5Param.getWordSize() != 32)
  458. {
  459. throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 32 not " + rc5Param.getWordSize() + ".");
  460. }
  461. }
  462. else if (baseEngine.getAlgorithmName().equals("RC5-64"))
  463. {
  464. if (rc5Param.getWordSize() != 64)
  465. {
  466. throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 64 not " + rc5Param.getWordSize() + ".");
  467. }
  468. }
  469. }
  470. else
  471. {
  472. throw new InvalidAlgorithmParameterException("RC5 parameters passed to a cipher that is not RC5.");
  473. }
  474. if ((rc5Param.getIV() != null) && (ivLength != 0))
  475. {
  476. param = new ParametersWithIV(param, rc5Param.getIV());
  477. ivParam = (ParametersWithIV)param;
  478. }
  479. }
  480. */
  481. else
  482. {
  483. throw new InvalidAlgorithmParameterException("unknown parameter type.");
  484. }
  485. if ((ivLength != 0) && !(param instanceof ParametersWithIV))
  486. {
  487. SecureRandom ivRandom = random;
  488. if (ivRandom == null)
  489. {
  490. ivRandom = new SecureRandom();
  491. }
  492. if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
  493. {
  494. byte[] iv = new byte[ivLength];
  495. ivRandom.nextBytes(iv);
  496. param = new ParametersWithIV(param, iv);
  497. ivParam = (ParametersWithIV)param;
  498. }
  499. else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
  500. {
  501. throw new InvalidAlgorithmParameterException("no IV set when one expected");
  502. }
  503. }
  504. if (random != null && padded)
  505. {
  506. param = new ParametersWithRandom(param, random);
  507. }
  508. try
  509. {
  510. switch (opmode)
  511. {
  512. case Cipher.ENCRYPT_MODE:
  513. case Cipher.WRAP_MODE:
  514. cipher.init(true, param);
  515. break;
  516. case Cipher.DECRYPT_MODE:
  517. case Cipher.UNWRAP_MODE:
  518. cipher.init(false, param);
  519. break;
  520. default:
  521. throw new InvalidParameterException("unknown opmode " + opmode + " passed");
  522. }
  523. }
  524. catch (Exception e)
  525. {
  526. throw new InvalidKeyException(e.getMessage());
  527. }
  528. }
  529. protected void engineInit(
  530. int opmode,
  531. Key key,
  532. AlgorithmParameters params,
  533. SecureRandom random)
  534. throws InvalidKeyException, InvalidAlgorithmParameterException
  535. {
  536. AlgorithmParameterSpec paramSpec = null;
  537. if (params != null)
  538. {
  539. for (int i = 0; i != availableSpecs.length; i++)
  540. {
  541. try
  542. {
  543. paramSpec = params.getParameterSpec(availableSpecs[i]);
  544. break;
  545. }
  546. catch (Exception e)
  547. {
  548. // try again if possible
  549. }
  550. }
  551. if (paramSpec == null)
  552. {
  553. throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
  554. }
  555. }
  556. engineInit(opmode, key, paramSpec, random);
  557. engineParams = params;
  558. }
  559. protected void engineInit(
  560. int opmode,
  561. Key key,
  562. SecureRandom random)
  563. throws InvalidKeyException
  564. {
  565. try
  566. {
  567. engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
  568. }
  569. catch (InvalidAlgorithmParameterException e)
  570. {
  571. throw new InvalidKeyException(e.getMessage());
  572. }
  573. }
  574. protected byte[] engineUpdate(
  575. byte[] input,
  576. int inputOffset,
  577. int inputLen)
  578. {
  579. int length = cipher.getUpdateOutputSize(inputLen);
  580. if (length > 0)
  581. {
  582. byte[] out = new byte[length];
  583. int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
  584. if (len == 0)
  585. {
  586. return null;
  587. }
  588. else if (len != out.length)
  589. {
  590. byte[] tmp = new byte[len];
  591. System.arraycopy(out, 0, tmp, 0, len);
  592. return tmp;
  593. }
  594. return out;
  595. }
  596. cipher.processBytes(input, inputOffset, inputLen, null, 0);
  597. return null;
  598. }
  599. protected int engineUpdate(
  600. byte[] input,
  601. int inputOffset,
  602. int inputLen,
  603. byte[] output,
  604. int outputOffset)
  605. throws ShortBufferException
  606. {
  607. try
  608. {
  609. return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
  610. }
  611. catch (DataLengthException e)
  612. {
  613. throw new ShortBufferException(e.getMessage());
  614. }
  615. }
  616. protected byte[] engineDoFinal(
  617. byte[] input,
  618. int inputOffset,
  619. int inputLen)
  620. throws IllegalBlockSizeException, BadPaddingException
  621. {
  622. int len = 0;
  623. byte[] tmp = new byte[engineGetOutputSize(inputLen)];
  624. if (inputLen != 0)
  625. {
  626. len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0);
  627. }
  628. try
  629. {
  630. len += cipher.doFinal(tmp, len);
  631. }
  632. catch (DataLengthException e)
  633. {
  634. throw new IllegalBlockSizeException(e.getMessage());
  635. }
  636. catch (InvalidCipherTextException e)
  637. {
  638. throw new BadPaddingException(e.getMessage());
  639. }
  640. if (len == tmp.length)
  641. {
  642. return tmp;
  643. }
  644. byte[] out = new byte[len];
  645. System.arraycopy(tmp, 0, out, 0, len);
  646. return out;
  647. }
  648. protected int engineDoFinal(
  649. byte[] input,
  650. int inputOffset,
  651. int inputLen,
  652. byte[] output,
  653. int outputOffset)
  654. throws IllegalBlockSizeException, BadPaddingException
  655. {
  656. int len = 0;
  657. if (inputLen != 0)
  658. {
  659. len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
  660. }
  661. try
  662. {
  663. return (len + cipher.doFinal(output, outputOffset + len));
  664. }
  665. catch (DataLengthException e)
  666. {
  667. throw new IllegalBlockSizeException(e.getMessage());
  668. }
  669. catch (InvalidCipherTextException e)
  670. {
  671. throw new BadPaddingException(e.getMessage());
  672. }
  673. }
  674. private boolean isAEADModeName(
  675. String modeName)
  676. {
  677. return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName);
  678. }
  679. /*
  680. * The ciphers that inherit from us.
  681. */
  682. /**
  683. * DES
  684. */
  685. /*
  686. static public class DES
  687. extends JCEBlockCipher
  688. {
  689. public DES()
  690. {
  691. super(new DESEngine());
  692. }
  693. }
  694. */
  695. /**
  696. * DESCBC
  697. */
  698. /*
  699. static public class DESCBC
  700. extends JCEBlockCipher
  701. {
  702. public DESCBC()
  703. {
  704. super(new CBCBlockCipher(new DESEngine()), 64);
  705. }
  706. }
  707. */
  708. /**
  709. * DESede
  710. */
  711. /*
  712. static public class DESede
  713. extends JCEBlockCipher
  714. {
  715. public DESede()
  716. {
  717. super(new DESedeEngine());
  718. }
  719. }
  720. */
  721. /**
  722. * DESedeCBC
  723. */
  724. /*
  725. static public class DESedeCBC
  726. extends JCEBlockCipher
  727. {
  728. public DESedeCBC()
  729. {
  730. super(new CBCBlockCipher(new DESedeEngine()), 64);
  731. }
  732. }
  733. */
  734. /**
  735. * GOST28147
  736. */
  737. /*
  738. static public class GOST28147
  739. extends JCEBlockCipher
  740. {
  741. public GOST28147()
  742. {
  743. super(new GOST28147Engine());
  744. }
  745. }
  746. static public class GOST28147cbc
  747. extends JCEBlockCipher
  748. {
  749. public GOST28147cbc()
  750. {
  751. super(new CBCBlockCipher(new GOST28147Engine()), 64);
  752. }
  753. }
  754. */
  755. /**
  756. * SKIPJACK
  757. */
  758. /*
  759. static public class Skipjack
  760. extends JCEBlockCipher
  761. {
  762. public Skipjack()
  763. {
  764. super(new SkipjackEngine());
  765. }
  766. }
  767. */
  768. /**
  769. * Blowfish
  770. */
  771. /*
  772. static public class Blowfish
  773. extends JCEBlockCipher
  774. {
  775. public Blowfish()
  776. {
  777. super(new BlowfishEngine());
  778. }
  779. }
  780. */
  781. /**
  782. * Blowfish CBC
  783. */
  784. /*
  785. static public class BlowfishCBC
  786. extends JCEBlockCipher
  787. {
  788. public BlowfishCBC()
  789. {
  790. super(new CBCBlockCipher(new BlowfishEngine()), 64);
  791. }
  792. }
  793. */
  794. /**
  795. * Twofish
  796. */
  797. static public class Twofish
  798. extends JCEBlockCipher
  799. {
  800. public Twofish()
  801. {
  802. super(new TwofishEngine());
  803. }
  804. }
  805. /**
  806. * RC2
  807. */
  808. /*
  809. static public class RC2
  810. extends JCEBlockCipher
  811. {
  812. public RC2()
  813. {
  814. super(new RC2Engine());
  815. }
  816. }
  817. */
  818. /**
  819. * RC2CBC
  820. */
  821. /*
  822. static public class RC2CBC
  823. extends JCEBlockCipher
  824. {
  825. public RC2CBC()
  826. {
  827. super(new CBCBlockCipher(new RC2Engine()), 64);
  828. }
  829. }
  830. */
  831. /**
  832. * RC5
  833. */
  834. /*
  835. static public class RC5
  836. extends JCEBlockCipher
  837. {
  838. public RC5()
  839. {
  840. super(new RC532Engine());
  841. }
  842. }
  843. */
  844. /**
  845. * RC564
  846. */
  847. /*
  848. static public class RC564
  849. extends JCEBlockCipher
  850. {
  851. public RC564()
  852. {
  853. super(new RC564Engine());
  854. }
  855. }
  856. */
  857. /**
  858. * RC6
  859. */
  860. /*
  861. static public class RC6
  862. extends JCEBlockCipher
  863. {
  864. public RC6()
  865. {
  866. super(new RC6Engine());
  867. }
  868. }
  869. /**
  870. * AES
  871. */
  872. /*
  873. static public class AES
  874. extends JCEBlockCipher
  875. {
  876. public AES()
  877. {
  878. super(new AESFastEngine());
  879. }
  880. }
  881. /**
  882. * AESCBC
  883. */
  884. /*
  885. static public class AESCBC
  886. extends JCEBlockCipher
  887. {
  888. public AESCBC()
  889. {
  890. super(new CBCBlockCipher(new AESFastEngine()), 128);
  891. }
  892. }
  893. /**
  894. * AESCFB
  895. */
  896. /*
  897. static public class AESCFB
  898. extends JCEBlockCipher
  899. {
  900. public AESCFB()
  901. {
  902. super(new CFBBlockCipher(new AESFastEngine(), 128), 128);
  903. }
  904. }
  905. /**
  906. * AESOFB
  907. */
  908. /*
  909. static public class AESOFB
  910. extends JCEBlockCipher
  911. {
  912. public AESOFB()
  913. {
  914. super(new OFBBlockCipher(new AESFastEngine(), 128), 128);
  915. }
  916. }
  917. /**
  918. * Rijndael
  919. */
  920. /*
  921. static public class Rijndael
  922. extends JCEBlockCipher
  923. {
  924. public Rijndael()
  925. {
  926. super(new RijndaelEngine());
  927. }
  928. }
  929. /**
  930. * Serpent
  931. */
  932. /*
  933. static public class Serpent
  934. extends JCEBlockCipher
  935. {
  936. public Serpent()
  937. {
  938. super(new SerpentEngine());
  939. }
  940. }
  941. /**
  942. * CAST5
  943. */
  944. /*
  945. static public class CAST5
  946. extends JCEBlockCipher
  947. {
  948. public CAST5()
  949. {
  950. super(new CAST5Engine());
  951. }
  952. }
  953. /**
  954. * CAST5 CBC
  955. */
  956. /*
  957. static public class CAST5CBC
  958. extends JCEBlockCipher
  959. {
  960. public CAST5CBC()
  961. {
  962. super(new CBCBlockCipher(new CAST5Engine()), 64);
  963. }
  964. }
  965. /**
  966. * CAST6
  967. */
  968. /*
  969. static public class CAST6
  970. extends JCEBlockCipher
  971. {
  972. public CAST6()
  973. {
  974. super(new CAST6Engine());
  975. }
  976. }
  977. /**
  978. * TEA
  979. */
  980. /*
  981. static public class TEA
  982. extends JCEBlockCipher
  983. {
  984. public TEA()
  985. {
  986. super(new TEAEngine());
  987. }
  988. }
  989. /**
  990. * XTEA
  991. */
  992. /*
  993. static public class XTEA
  994. extends JCEBlockCipher
  995. {
  996. public XTEA()
  997. {
  998. super(new XTEAEngine());
  999. }
  1000. }
  1001. /**
  1002. * SEED
  1003. */
  1004. /*
  1005. static public class SEED
  1006. extends JCEBlockCipher
  1007. {
  1008. public SEED()
  1009. {
  1010. super(new SEEDEngine());
  1011. }
  1012. }
  1013. /**
  1014. * PBEWithMD5AndDES
  1015. */
  1016. /*
  1017. static public class PBEWithMD5AndDES
  1018. extends JCEBlockCipher
  1019. {
  1020. public PBEWithMD5AndDES()
  1021. {
  1022. super(new CBCBlockCipher(new DESEngine()));
  1023. }
  1024. }
  1025. /**
  1026. * PBEWithMD5AndRC2
  1027. */
  1028. /*
  1029. static public class PBEWithMD5AndRC2
  1030. extends JCEBlockCipher
  1031. {
  1032. public PBEWithMD5AndRC2()
  1033. {
  1034. super(new CBCBlockCipher(new RC2Engine()));
  1035. }
  1036. }
  1037. /**
  1038. * PBEWithSHA1AndDES
  1039. */
  1040. /*
  1041. static public class PBEWithSHA1AndDES
  1042. extends JCEBlockCipher
  1043. {
  1044. public PBEWithSHA1AndDES()
  1045. {
  1046. super(new CBCBlockCipher(new DESEngine()));
  1047. }
  1048. }
  1049. /**
  1050. * PBEWithSHA1AndRC2
  1051. */
  1052. /*
  1053. static public class PBEWithSHA1AndRC2
  1054. extends JCEBlockCipher
  1055. {
  1056. public PBEWithSHA1AndRC2()
  1057. {
  1058. super(new CBCBlockCipher(new RC2Engine()));
  1059. }
  1060. }
  1061. /**
  1062. * PBEWithSHAAnd3-KeyTripleDES-CBC
  1063. */
  1064. /*
  1065. static public class PBEWithSHAAndDES3Key
  1066. extends JCEBlockCipher
  1067. {
  1068. public PBEWithSHAAndDES3Key()
  1069. {
  1070. super(new CBCBlockCipher(new DESedeEngine()));
  1071. }
  1072. }
  1073. /**
  1074. * PBEWithSHAAnd2-KeyTripleDES-CBC
  1075. */
  1076. /*
  1077. static public class PBEWithSHAAndDES2Key
  1078. extends JCEBlockCipher
  1079. {
  1080. public PBEWithSHAAndDES2Key()
  1081. {
  1082. super(new CBCBlockCipher(new DESedeEngine()));
  1083. }
  1084. }
  1085. /**
  1086. * PBEWithSHAAnd128BitRC2-CBC
  1087. */
  1088. /*
  1089. static public class PBEWithSHAAnd128BitRC2
  1090. extends JCEBlockCipher
  1091. {
  1092. public PBEWithSHAAnd128BitRC2()
  1093. {
  1094. super(new CBCBlockCipher(new RC2Engine()));
  1095. }
  1096. }
  1097. /**
  1098. * PBEWithSHAAnd40BitRC2-CBC
  1099. */
  1100. /*
  1101. static public class PBEWithSHAAnd40BitRC2
  1102. extends JCEBlockCipher
  1103. {
  1104. public PBEWithSHAAnd40BitRC2()
  1105. {
  1106. super(new CBCBlockCipher(new RC2Engine()));
  1107. }
  1108. }
  1109. /**
  1110. * PBEWithSHAAndTwofish-CBC
  1111. */
  1112. static public class PBEWithSHAAndTwofish
  1113. extends JCEBlockCipher
  1114. {
  1115. public PBEWithSHAAndTwofish()
  1116. {
  1117. super(new CBCBlockCipher(new TwofishEngine()));
  1118. }
  1119. }
  1120. /**
  1121. * PBEWithAES-CBC
  1122. */
  1123. /*
  1124. static public class PBEWithAESCBC
  1125. extends JCEBlockCipher
  1126. {
  1127. public PBEWithAESCBC()
  1128. {
  1129. super(new CBCBlockCipher(new AESFastEngine()));
  1130. }
  1131. }
  1132. */
  1133. static private interface GenericBlockCipher
  1134. {
  1135. public void init(boolean forEncryption, CipherParameters params)
  1136. throws IllegalArgumentException;
  1137. public boolean wrapOnNoPadding();
  1138. public String getAlgorithmName();
  1139. public BlockCipher getUnderlyingCipher();
  1140. public int getOutputSize(int len);
  1141. public int getUpdateOutputSize(int len);
  1142. public int processByte(byte in, byte[] out, int outOff)
  1143. throws DataLengthException;
  1144. public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
  1145. throws DataLengthException;
  1146. public int doFinal(byte[] out, int outOff)
  1147. throws IllegalStateException, InvalidCipherTextException;
  1148. }
  1149. private static class BufferedGenericBlockCipher
  1150. implements GenericBlockCipher
  1151. {
  1152. private BufferedBlockCipher cipher;
  1153. BufferedGenericBlockCipher(BufferedBlockCipher cipher)
  1154. {
  1155. this.cipher = cipher;
  1156. }
  1157. BufferedGenericBlockCipher(BlockCipher cipher)
  1158. {
  1159. this.cipher = new PaddedBufferedBlockCipher(cipher);
  1160. }
  1161. /*
  1162. BufferedGenericBlockCipher(BlockCipher cipher, BlockCipherPadding padding)
  1163. {
  1164. this.cipher = new PaddedBufferedBlockCipher(cipher, padding);
  1165. }
  1166. */
  1167. public void init(boolean forEncryption, CipherParameters params)
  1168. throws IllegalArgumentException
  1169. {
  1170. cipher.init(forEncryption, params);
  1171. }
  1172. public boolean wrapOnNoPadding()
  1173. {
  1174. return !(cipher instanceof CTSBlockCipher);
  1175. }
  1176. public String getAlgorithmName()
  1177. {
  1178. return cipher.getUnderlyingCipher().getAlgorithmName();
  1179. }
  1180. public BlockCipher getUnderlyingCipher()
  1181. {
  1182. return cipher.getUnderlyingCipher();
  1183. }
  1184. public int getOutputSize(int len)
  1185. {
  1186. return cipher.getOutputSize(len);
  1187. }
  1188. public int getUpdateOutputSize(int len)
  1189. {
  1190. return cipher.getUpdateOutputSize(len);
  1191. }
  1192. public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
  1193. {
  1194. return cipher.processByte(in, out, outOff);
  1195. }
  1196. public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
  1197. {
  1198. return cipher.processBytes(in, inOff, len, out, outOff);
  1199. }
  1200. public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException
  1201. {
  1202. return cipher.doFinal(out, outOff);
  1203. }
  1204. }
  1205. /*
  1206. private static class AEADGenericBlockCipher
  1207. implements GenericBlockCipher
  1208. {
  1209. private AEADBlockCipher cipher;
  1210. AEADGenericBlockCipher(AEADBlockCipher cipher)
  1211. {
  1212. this.cipher = cipher;
  1213. }
  1214. public void init(boolean forEncryption, CipherParameters params)
  1215. throws IllegalArgumentException
  1216. {
  1217. cipher.init(forEncryption, params);
  1218. }
  1219. public String getAlgorithmName()
  1220. {
  1221. return cipher.getUnderlyingCipher().getAlgorithmName();
  1222. }
  1223. public boolean wrapOnNoPadding()
  1224. {
  1225. return false;
  1226. }
  1227. public BlockCipher getUnderlyingCipher()
  1228. {
  1229. return cipher.getUnderlyingCipher();
  1230. }
  1231. public int getOutputSize(int len)
  1232. {
  1233. return cipher.getOutputSize(len);
  1234. }
  1235. public int getUpdateOutputSize(int len)
  1236. {
  1237. return cipher.getUpdateOutputSize(len);
  1238. }
  1239. public int processByte(byte in, byte[] out, int outOff) throws DataLengthException
  1240. {
  1241. return cipher.processByte(in, out, outOff);
  1242. }
  1243. public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
  1244. {
  1245. return cipher.processBytes(in, inOff, len, out, outOff);
  1246. }
  1247. public int doFinal(byte[] out, int outOff) throws IllegalStateException, InvalidCipherTextException
  1248. {
  1249. return cipher.doFinal(out, outOff);
  1250. }
  1251. }
  1252. */
  1253. }