PageRenderTime 49ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

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

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