PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

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

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