PageRenderTime 24ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/MIPS/external-bouncycastle
Java | 604 lines | 321 code | 55 blank | 228 comment | 42 complexity | 3b1e06b966c5feae06d6ee701aca4144 MD5 | raw file
  1. package org.bouncycastle.jce.provider;
  2. import org.bouncycastle.crypto.BlockCipher;
  3. import org.bouncycastle.crypto.CipherParameters;
  4. import org.bouncycastle.crypto.DataLengthException;
  5. import org.bouncycastle.crypto.StreamBlockCipher;
  6. import org.bouncycastle.crypto.StreamCipher;
  7. // BEGIN android-removed
  8. // import org.bouncycastle.crypto.engines.BlowfishEngine;
  9. // import org.bouncycastle.crypto.engines.DESEngine;
  10. // import org.bouncycastle.crypto.engines.DESedeEngine;
  11. // import org.bouncycastle.crypto.engines.HC128Engine;
  12. // import org.bouncycastle.crypto.engines.HC256Engine;
  13. // END android-removed
  14. import org.bouncycastle.crypto.engines.RC4Engine;
  15. // BEGIN android-removed
  16. // import org.bouncycastle.crypto.engines.Salsa20Engine;
  17. // import org.bouncycastle.crypto.engines.SkipjackEngine;
  18. // import org.bouncycastle.crypto.engines.TwofishEngine;
  19. // import org.bouncycastle.crypto.engines.VMPCEngine;
  20. // import org.bouncycastle.crypto.engines.VMPCKSA3Engine;
  21. // END android-removed
  22. import org.bouncycastle.crypto.modes.CFBBlockCipher;
  23. import org.bouncycastle.crypto.modes.OFBBlockCipher;
  24. import org.bouncycastle.crypto.params.KeyParameter;
  25. import org.bouncycastle.crypto.params.ParametersWithIV;
  26. import javax.crypto.Cipher;
  27. import javax.crypto.NoSuchPaddingException;
  28. import javax.crypto.SecretKey;
  29. import javax.crypto.ShortBufferException;
  30. import javax.crypto.spec.IvParameterSpec;
  31. import javax.crypto.spec.PBEParameterSpec;
  32. // BEGIN android-removed
  33. // import javax.crypto.spec.RC2ParameterSpec;
  34. // import javax.crypto.spec.RC5ParameterSpec;
  35. // END android-removed
  36. import java.security.AlgorithmParameters;
  37. import java.security.InvalidAlgorithmParameterException;
  38. import java.security.InvalidKeyException;
  39. import java.security.Key;
  40. import java.security.SecureRandom;
  41. import java.security.spec.AlgorithmParameterSpec;
  42. public class JCEStreamCipher
  43. extends WrapCipherSpi implements PBE
  44. {
  45. //
  46. // specs we can handle.
  47. //
  48. private Class[] availableSpecs =
  49. {
  50. // BEGIN android-removed
  51. // RC2ParameterSpec.class,
  52. // RC5ParameterSpec.class,
  53. // END android-removed
  54. IvParameterSpec.class,
  55. PBEParameterSpec.class
  56. };
  57. private StreamCipher cipher;
  58. private ParametersWithIV ivParam;
  59. private int ivLength = 0;
  60. private PBEParameterSpec pbeSpec = null;
  61. private String pbeAlgorithm = null;
  62. protected JCEStreamCipher(
  63. StreamCipher engine,
  64. int ivLength)
  65. {
  66. cipher = engine;
  67. this.ivLength = ivLength;
  68. }
  69. protected JCEStreamCipher(
  70. BlockCipher engine,
  71. int ivLength)
  72. {
  73. this.ivLength = ivLength;
  74. cipher = new StreamBlockCipher(engine);
  75. }
  76. protected int engineGetBlockSize()
  77. {
  78. return 0;
  79. }
  80. protected byte[] engineGetIV()
  81. {
  82. return (ivParam != null) ? ivParam.getIV() : null;
  83. }
  84. protected int engineGetKeySize(
  85. Key key)
  86. {
  87. return key.getEncoded().length * 8;
  88. }
  89. protected int engineGetOutputSize(
  90. int inputLen)
  91. {
  92. return inputLen;
  93. }
  94. protected AlgorithmParameters engineGetParameters()
  95. {
  96. if (engineParams == null)
  97. {
  98. if (pbeSpec != null)
  99. {
  100. try
  101. {
  102. AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, "BC");
  103. engineParams.init(pbeSpec);
  104. return engineParams;
  105. }
  106. catch (Exception e)
  107. {
  108. return null;
  109. }
  110. }
  111. }
  112. return engineParams;
  113. }
  114. /**
  115. * should never be called.
  116. */
  117. protected void engineSetMode(
  118. String mode)
  119. {
  120. if (!mode.equalsIgnoreCase("ECB"))
  121. {
  122. throw new IllegalArgumentException("can't support mode " + mode);
  123. }
  124. }
  125. /**
  126. * should never be called.
  127. */
  128. protected void engineSetPadding(
  129. String padding)
  130. throws NoSuchPaddingException
  131. {
  132. if (!padding.equalsIgnoreCase("NoPadding"))
  133. {
  134. throw new NoSuchPaddingException("Padding " + padding + " unknown.");
  135. }
  136. }
  137. protected void engineInit(
  138. int opmode,
  139. Key key,
  140. AlgorithmParameterSpec params,
  141. SecureRandom random)
  142. throws InvalidKeyException, InvalidAlgorithmParameterException
  143. {
  144. CipherParameters param;
  145. this.pbeSpec = null;
  146. this.pbeAlgorithm = null;
  147. this.engineParams = null;
  148. //
  149. // basic key check
  150. //
  151. if (!(key instanceof SecretKey))
  152. {
  153. throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
  154. }
  155. if (key instanceof JCEPBEKey)
  156. {
  157. JCEPBEKey k = (JCEPBEKey)key;
  158. if (k.getOID() != null)
  159. {
  160. pbeAlgorithm = k.getOID().getId();
  161. }
  162. else
  163. {
  164. pbeAlgorithm = k.getAlgorithm();
  165. }
  166. if (k.getParam() != null)
  167. {
  168. param = k.getParam();
  169. pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
  170. }
  171. else if (params instanceof PBEParameterSpec)
  172. {
  173. param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName());
  174. pbeSpec = (PBEParameterSpec)params;
  175. }
  176. else
  177. {
  178. throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
  179. }
  180. if (k.getIvSize() != 0)
  181. {
  182. ivParam = (ParametersWithIV)param;
  183. }
  184. }
  185. else if (params == null)
  186. {
  187. param = new KeyParameter(key.getEncoded());
  188. }
  189. else if (params instanceof IvParameterSpec)
  190. {
  191. param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV());
  192. ivParam = (ParametersWithIV)param;
  193. }
  194. else
  195. {
  196. throw new IllegalArgumentException("unknown parameter type.");
  197. }
  198. if ((ivLength != 0) && !(param instanceof ParametersWithIV))
  199. {
  200. SecureRandom ivRandom = random;
  201. if (ivRandom == null)
  202. {
  203. ivRandom = new SecureRandom();
  204. }
  205. if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
  206. {
  207. byte[] iv = new byte[ivLength];
  208. ivRandom.nextBytes(iv);
  209. param = new ParametersWithIV(param, iv);
  210. ivParam = (ParametersWithIV)param;
  211. }
  212. else
  213. {
  214. throw new InvalidAlgorithmParameterException("no IV set when one expected");
  215. }
  216. }
  217. switch (opmode)
  218. {
  219. case Cipher.ENCRYPT_MODE:
  220. case Cipher.WRAP_MODE:
  221. cipher.init(true, param);
  222. break;
  223. case Cipher.DECRYPT_MODE:
  224. case Cipher.UNWRAP_MODE:
  225. cipher.init(false, param);
  226. break;
  227. default:
  228. System.out.println("eeek!");
  229. }
  230. }
  231. protected void engineInit(
  232. int opmode,
  233. Key key,
  234. AlgorithmParameters params,
  235. SecureRandom random)
  236. throws InvalidKeyException, InvalidAlgorithmParameterException
  237. {
  238. AlgorithmParameterSpec paramSpec = null;
  239. if (params != null)
  240. {
  241. for (int i = 0; i != availableSpecs.length; i++)
  242. {
  243. try
  244. {
  245. paramSpec = params.getParameterSpec(availableSpecs[i]);
  246. break;
  247. }
  248. catch (Exception e)
  249. {
  250. continue;
  251. }
  252. }
  253. if (paramSpec == null)
  254. {
  255. throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
  256. }
  257. }
  258. engineInit(opmode, key, paramSpec, random);
  259. engineParams = params;
  260. }
  261. protected void engineInit(
  262. int opmode,
  263. Key key,
  264. SecureRandom random)
  265. throws InvalidKeyException
  266. {
  267. try
  268. {
  269. engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
  270. }
  271. catch (InvalidAlgorithmParameterException e)
  272. {
  273. throw new InvalidKeyException(e.getMessage());
  274. }
  275. }
  276. protected byte[] engineUpdate(
  277. byte[] input,
  278. int inputOffset,
  279. int inputLen)
  280. {
  281. byte[] out = new byte[inputLen];
  282. cipher.processBytes(input, inputOffset, inputLen, out, 0);
  283. return out;
  284. }
  285. protected int engineUpdate(
  286. byte[] input,
  287. int inputOffset,
  288. int inputLen,
  289. byte[] output,
  290. int outputOffset)
  291. throws ShortBufferException
  292. {
  293. try
  294. {
  295. cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
  296. return inputLen;
  297. }
  298. catch (DataLengthException e)
  299. {
  300. throw new ShortBufferException(e.getMessage());
  301. }
  302. }
  303. protected byte[] engineDoFinal(
  304. byte[] input,
  305. int inputOffset,
  306. int inputLen)
  307. {
  308. if (inputLen != 0)
  309. {
  310. byte[] out = engineUpdate(input, inputOffset, inputLen);
  311. cipher.reset();
  312. return out;
  313. }
  314. cipher.reset();
  315. return new byte[0];
  316. }
  317. protected int engineDoFinal(
  318. byte[] input,
  319. int inputOffset,
  320. int inputLen,
  321. byte[] output,
  322. int outputOffset)
  323. {
  324. if (inputLen != 0)
  325. {
  326. cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
  327. }
  328. cipher.reset();
  329. return inputLen;
  330. }
  331. /*
  332. * The ciphers that inherit from us.
  333. */
  334. // BEGIN android-removed
  335. // /**
  336. // * DES
  337. // */
  338. // static public class DES_CFB8
  339. // extends JCEStreamCipher
  340. // {
  341. // public DES_CFB8()
  342. // {
  343. // super(new CFBBlockCipher(new DESEngine(), 8), 64);
  344. // }
  345. // }
  346. //
  347. // /**
  348. // * DESede
  349. // */
  350. // static public class DESede_CFB8
  351. // extends JCEStreamCipher
  352. // {
  353. // public DESede_CFB8()
  354. // {
  355. // super(new CFBBlockCipher(new DESedeEngine(), 8), 64);
  356. // }
  357. // }
  358. //
  359. // /**
  360. // * SKIPJACK
  361. // */
  362. // static public class Skipjack_CFB8
  363. // extends JCEStreamCipher
  364. // {
  365. // public Skipjack_CFB8()
  366. // {
  367. // super(new CFBBlockCipher(new SkipjackEngine(), 8), 64);
  368. // }
  369. // }
  370. //
  371. // /**
  372. // * Blowfish
  373. // */
  374. // static public class Blowfish_CFB8
  375. // extends JCEStreamCipher
  376. // {
  377. // public Blowfish_CFB8()
  378. // {
  379. // super(new CFBBlockCipher(new BlowfishEngine(), 8), 64);
  380. // }
  381. // }
  382. //
  383. // /**
  384. // * Twofish
  385. // */
  386. // static public class Twofish_CFB8
  387. // extends JCEStreamCipher
  388. // {
  389. // public Twofish_CFB8()
  390. // {
  391. // super(new CFBBlockCipher(new TwofishEngine(), 8), 128);
  392. // }
  393. // }
  394. //
  395. // /**
  396. // * DES
  397. // */
  398. // static public class DES_OFB8
  399. // extends JCEStreamCipher
  400. // {
  401. // public DES_OFB8()
  402. // {
  403. // super(new OFBBlockCipher(new DESEngine(), 8), 64);
  404. // }
  405. // }
  406. //
  407. // /**
  408. // * DESede
  409. // */
  410. // static public class DESede_OFB8
  411. // extends JCEStreamCipher
  412. // {
  413. // public DESede_OFB8()
  414. // {
  415. // super(new OFBBlockCipher(new DESedeEngine(), 8), 64);
  416. // }
  417. // }
  418. //
  419. // /**
  420. // * SKIPJACK
  421. // */
  422. // static public class Skipjack_OFB8
  423. // extends JCEStreamCipher
  424. // {
  425. // public Skipjack_OFB8()
  426. // {
  427. // super(new OFBBlockCipher(new SkipjackEngine(), 8), 64);
  428. // }
  429. // }
  430. //
  431. // /**
  432. // * Blowfish
  433. // */
  434. // static public class Blowfish_OFB8
  435. // extends JCEStreamCipher
  436. // {
  437. // public Blowfish_OFB8()
  438. // {
  439. // super(new OFBBlockCipher(new BlowfishEngine(), 8), 64);
  440. // }
  441. // }
  442. //
  443. // /**
  444. // * Twofish
  445. // */
  446. // static public class Twofish_OFB8
  447. // extends JCEStreamCipher
  448. // {
  449. // public Twofish_OFB8()
  450. // {
  451. // super(new OFBBlockCipher(new TwofishEngine(), 8), 128);
  452. // }
  453. // }
  454. // END android-removed
  455. /**
  456. * RC4
  457. */
  458. static public class RC4
  459. extends JCEStreamCipher
  460. {
  461. public RC4()
  462. {
  463. super(new RC4Engine(), 0);
  464. }
  465. }
  466. /**
  467. * PBEWithSHAAnd128BitRC4
  468. */
  469. static public class PBEWithSHAAnd128BitRC4
  470. extends JCEStreamCipher
  471. {
  472. public PBEWithSHAAnd128BitRC4()
  473. {
  474. super(new RC4Engine(), 0);
  475. }
  476. }
  477. /**
  478. * PBEWithSHAAnd40BitRC4
  479. */
  480. static public class PBEWithSHAAnd40BitRC4
  481. extends JCEStreamCipher
  482. {
  483. public PBEWithSHAAnd40BitRC4()
  484. {
  485. super(new RC4Engine(), 0);
  486. }
  487. }
  488. // BEGIN android-removed
  489. // /**
  490. // * Salsa20
  491. // */
  492. // static public class Salsa20
  493. // extends JCEStreamCipher
  494. // {
  495. // public Salsa20()
  496. // {
  497. // super(new Salsa20Engine(), 8);
  498. // }
  499. // }
  500. //
  501. // /**
  502. // * HC-128
  503. // */
  504. // static public class HC128
  505. // extends JCEStreamCipher
  506. // {
  507. // public HC128()
  508. // {
  509. // super(new HC128Engine(), 16);
  510. // }
  511. // }
  512. //
  513. // /**
  514. // * HC-256
  515. // */
  516. // static public class HC256
  517. // extends JCEStreamCipher
  518. // {
  519. // public HC256()
  520. // {
  521. // super(new HC256Engine(), 32);
  522. // }
  523. // }
  524. //
  525. // /**
  526. // * VMPC
  527. // */
  528. // static public class VMPC
  529. // extends JCEStreamCipher
  530. // {
  531. // public VMPC()
  532. // {
  533. // super(new VMPCEngine(), 16);
  534. // }
  535. // }
  536. //
  537. // /**
  538. // * VMPC-KSA3
  539. // */
  540. // static public class VMPCKSA3
  541. // extends JCEStreamCipher
  542. // {
  543. // public VMPCKSA3()
  544. // {
  545. // super(new VMPCKSA3Engine(), 16);
  546. // }
  547. // }
  548. // END android-removed
  549. }