21
21
import javax .crypto .interfaces .DHPrivateKey ;
22
22
import javax .crypto .interfaces .DHPublicKey ;
23
23
24
- import org .bouncycastle .crypto .BlockCipher ;
24
+ import org .bouncycastle .crypto .CipherParameters ;
25
25
import org .bouncycastle .crypto .InvalidCipherTextException ;
26
26
import org .bouncycastle .crypto .KeyEncoder ;
27
27
import org .bouncycastle .crypto .agreement .DHBasicAgreement ;
28
28
import org .bouncycastle .crypto .digests .SHA1Digest ;
29
- import org .bouncycastle .crypto .engines .AESEngine ;
29
+ import org .bouncycastle .crypto .engines .AESFastEngine ;
30
30
import org .bouncycastle .crypto .engines .DESedeEngine ;
31
31
import org .bouncycastle .crypto .engines .IESEngine ;
32
- import org .bouncycastle .crypto .engines .OldIESEngine ;
33
32
import org .bouncycastle .crypto .generators .DHKeyPairGenerator ;
34
33
import org .bouncycastle .crypto .generators .EphemeralKeyPairGenerator ;
35
34
import org .bouncycastle .crypto .generators .KDF2BytesGenerator ;
36
35
import org .bouncycastle .crypto .macs .HMac ;
36
+ import org .bouncycastle .crypto .modes .CBCBlockCipher ;
37
37
import org .bouncycastle .crypto .paddings .PaddedBufferedBlockCipher ;
38
38
import org .bouncycastle .crypto .params .AsymmetricKeyParameter ;
39
39
import org .bouncycastle .crypto .params .DHKeyGenerationParameters ;
40
40
import org .bouncycastle .crypto .params .DHKeyParameters ;
41
41
import org .bouncycastle .crypto .params .DHParameters ;
42
42
import org .bouncycastle .crypto .params .DHPublicKeyParameters ;
43
- import org .bouncycastle .crypto .params .IESParameters ;
44
43
import org .bouncycastle .crypto .params .IESWithCipherParameters ;
44
+ import org .bouncycastle .crypto .params .ParametersWithIV ;
45
45
import org .bouncycastle .crypto .parsers .DHIESPublicKeyParser ;
46
46
import org .bouncycastle .jcajce .provider .asymmetric .util .DHUtil ;
47
47
import org .bouncycastle .jcajce .provider .asymmetric .util .IESUtil ;
@@ -57,6 +57,7 @@ public class IESCipher
57
57
extends CipherSpi
58
58
{
59
59
private final JcaJceHelper helper = new BCJcaJceHelper ();
60
+ private final int ivLength ;
60
61
61
62
private IESEngine engine ;
62
63
private int state = -1 ;
@@ -71,11 +72,13 @@ public class IESCipher
71
72
public IESCipher (IESEngine engine )
72
73
{
73
74
this .engine = engine ;
75
+ this .ivLength = 0 ;
74
76
}
75
77
76
- public IESCipher (OldIESEngine engine )
78
+ public IESCipher (IESEngine engine , int ivLength )
77
79
{
78
80
this .engine = engine ;
81
+ this .ivLength = ivLength ;
79
82
}
80
83
81
84
public int engineGetBlockSize ()
@@ -106,6 +109,10 @@ public int engineGetKeySize(Key key)
106
109
107
110
public byte [] engineGetIV ()
108
111
{
112
+ if (engineSpec != null )
113
+ {
114
+ return engineSpec .getNonce ();
115
+ }
109
116
return null ;
110
117
}
111
118
@@ -257,7 +264,13 @@ public void engineInit(
257
264
// Use default parameters (including cipher key size) if none are specified
258
265
if (engineSpec == null )
259
266
{
260
- this .engineSpec = IESUtil .guessParameterSpec (engine .getCipher ());
267
+ byte [] nonce = null ;
268
+ if (ivLength != 0 && opmode == Cipher .ENCRYPT_MODE )
269
+ {
270
+ nonce = new byte [ivLength ];
271
+ random .nextBytes (nonce );
272
+ }
273
+ this .engineSpec = IESUtil .guessParameterSpec (engine .getCipher (), nonce );
261
274
}
262
275
else if (engineSpec instanceof IESParameterSpec )
263
276
{
@@ -268,6 +281,13 @@ else if (engineSpec instanceof IESParameterSpec)
268
281
throw new InvalidAlgorithmParameterException ("must be passed IES parameters" );
269
282
}
270
283
284
+ byte [] nonce = this .engineSpec .getNonce ();
285
+
286
+ if (ivLength != 0 && (nonce == null || nonce .length != ivLength ))
287
+ {
288
+ throw new InvalidAlgorithmParameterException ("NONCE in IES Parameters needs to be " + ivLength + " bytes long" );
289
+ }
290
+
271
291
// Parse the recipient's key
272
292
if (opmode == Cipher .ENCRYPT_MODE || opmode == Cipher .WRAP_MODE )
273
293
{
@@ -329,7 +349,7 @@ public void engineInit(
329
349
}
330
350
catch (InvalidAlgorithmParameterException e )
331
351
{
332
- throw new IllegalArgumentException ("can't handle supplied parameter spec" );
352
+ throw new IllegalArgumentException ("cannot handle supplied parameter spec: " + e . getMessage () );
333
353
}
334
354
335
355
}
@@ -376,11 +396,16 @@ public byte[] engineDoFinal(
376
396
buffer .reset ();
377
397
378
398
// Convert parameters for use in IESEngine
379
- IESParameters params = new IESWithCipherParameters (engineSpec .getDerivationV (),
399
+ CipherParameters params = new IESWithCipherParameters (engineSpec .getDerivationV (),
380
400
engineSpec .getEncodingV (),
381
401
engineSpec .getMacKeySize (),
382
402
engineSpec .getCipherKeySize ());
383
403
404
+ if (engineSpec .getNonce () != null )
405
+ {
406
+ params = new ParametersWithIV (params , engineSpec .getNonce ());
407
+ }
408
+
384
409
DHParameters dhParams = ((DHKeyParameters )key ).getParameters ();
385
410
386
411
byte [] V ;
@@ -494,71 +519,27 @@ public IES()
494
519
}
495
520
}
496
521
497
- static public class IESwithDESede
522
+ static public class IESwithDESedeCBC
498
523
extends IESCipher
499
524
{
500
- public IESwithDESede ()
525
+ public IESwithDESedeCBC ()
501
526
{
502
527
super (new IESEngine (new DHBasicAgreement (),
503
528
new KDF2BytesGenerator (new SHA1Digest ()),
504
529
new HMac (new SHA1Digest ()),
505
- new PaddedBufferedBlockCipher (new DESedeEngine ())));
530
+ new PaddedBufferedBlockCipher (new CBCBlockCipher ( new DESedeEngine ()))), 8 );
506
531
}
507
532
}
508
533
509
- static public class IESwithAES
534
+ static public class IESwithAESCBC
510
535
extends IESCipher
511
536
{
512
- public IESwithAES ()
537
+ public IESwithAESCBC ()
513
538
{
514
539
super (new IESEngine (new DHBasicAgreement (),
515
540
new KDF2BytesGenerator (new SHA1Digest ()),
516
541
new HMac (new SHA1Digest ()),
517
- new PaddedBufferedBlockCipher (new AESEngine ())));
518
- }
519
- }
520
-
521
- /**
522
- * Backwards compatibility.
523
- */
524
- static public class OldIESwithCipher
525
- extends IESCipher
526
- {
527
- public OldIESwithCipher (BlockCipher baseCipher )
528
- {
529
- super (new OldIESEngine (new DHBasicAgreement (),
530
- new KDF2BytesGenerator (new SHA1Digest ()),
531
- new HMac (new SHA1Digest ()),
532
- new PaddedBufferedBlockCipher (baseCipher )));
533
- }
534
- }
535
-
536
- static public class OldIES
537
- extends IESCipher
538
- {
539
- public OldIES ()
540
- {
541
- super (new OldIESEngine (new DHBasicAgreement (),
542
- new KDF2BytesGenerator (new SHA1Digest ()),
543
- new HMac (new SHA1Digest ())));
544
- }
545
- }
546
-
547
- static public class OldIESwithDESede
548
- extends OldIESwithCipher
549
- {
550
- public OldIESwithDESede ()
551
- {
552
- super (new DESedeEngine ());
553
- }
554
- }
555
-
556
- static public class OldIESwithAES
557
- extends OldIESwithCipher
558
- {
559
- public OldIESwithAES ()
560
- {
561
- super (new AESEngine ());
542
+ new PaddedBufferedBlockCipher (new CBCBlockCipher (new AESFastEngine ()))), 16 );
562
543
}
563
544
}
564
545
}
0 commit comments