PageRenderTime 80ms CodeModel.GetById 49ms RepoModel.GetById 0ms app.codeStats 1ms

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

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