PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

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

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