3
3
import org .bouncycastle .crypto .Digest ;
4
4
import org .bouncycastle .crypto .digests .Blake2bDigest ;
5
5
import org .bouncycastle .crypto .params .Argon2Parameters ;
6
+ import org .bouncycastle .crypto .params .Argon2Parameters .BlockPool ;
7
+ import org .bouncycastle .crypto .params .Argon2Parameters .FixedBlockPool ;
6
8
import org .bouncycastle .util .Arrays ;
7
9
import org .bouncycastle .util .Longs ;
8
10
import org .bouncycastle .util .Pack ;
@@ -37,6 +39,8 @@ public class Argon2BytesGenerator
37
39
private static final byte [] ZERO_BYTES = new byte [4 ];
38
40
39
41
private Argon2Parameters parameters ;
42
+ private BlockPool pool ;
43
+ private int memoryBlocks ;
40
44
private Block [] memory ;
41
45
private int segmentLength ;
42
46
private int laneLength ;
@@ -90,10 +94,11 @@ else if (parameters.getIterations() < MIN_ITERATIONS)
90
94
memoryBlocks = parameters .getLanes () * laneLength ;
91
95
92
96
this .memory = new Block [memoryBlocks ];
93
-
94
- for (int i = 0 ; i < memory .length ; i ++)
95
- {
96
- memory [i ] = new Block ();
97
+
98
+ pool = parameters .getBlockPool ();
99
+ if (pool == null ) {
100
+ // if no pool is provided hold on to enough blocks for the primary memory
101
+ pool = new FixedBlockPool (memoryBlocks );
97
102
}
98
103
}
99
104
@@ -121,6 +126,7 @@ public int generateBytes(byte[] password, byte[] out, int outOff, int outLen)
121
126
122
127
byte [] tmpBlockBytes = new byte [ARGON2_BLOCK_SIZE ];
123
128
129
+ initMemory (memoryBlocks );
124
130
initialize (tmpBlockBytes , password , outLen );
125
131
fillMemoryBlocks ();
126
132
digest (tmpBlockBytes , out , outOff , outLen );
@@ -141,15 +147,26 @@ private void reset()
141
147
Block b = memory [i ];
142
148
if (null != b )
143
149
{
144
- b . clear ( );
150
+ pool . deallocate ( b );
145
151
}
146
152
}
147
153
}
154
+ memory = null ;
155
+ }
156
+
157
+ private void initMemory (int memoryBlocks )
158
+ {
159
+ this .memory = new Block [memoryBlocks ];
160
+
161
+ for (int i = 0 ; i < memory .length ; i ++)
162
+ {
163
+ memory [i ] = pool .allocate ();
164
+ }
148
165
}
149
166
150
167
private void fillMemoryBlocks ()
151
168
{
152
- FillBlock filler = new FillBlock ();
169
+ FillBlock filler = new FillBlock (pool );
153
170
Position position = new Position ();
154
171
for (int pass = 0 ; pass < parameters .getIterations (); ++pass )
155
172
{
@@ -167,6 +184,7 @@ private void fillMemoryBlocks()
167
184
}
168
185
}
169
186
}
187
+ filler .deallocate (pool );
170
188
}
171
189
172
190
private void fillSegment (FillBlock filler , Position position )
@@ -541,16 +559,31 @@ private void fillFirstBlocks(byte[] tmpBlockBytes, byte[] initialHashWithZeros)
541
559
542
560
private long intToLong (int x )
543
561
{
544
- return ( long )( x & M32L ) ;
562
+ return x & M32L ;
545
563
}
546
564
547
565
private static class FillBlock
548
566
{
549
- Block R = new Block ();
550
- Block Z = new Block ();
567
+ final Block R ;
568
+ final Block Z ;
569
+
570
+ final Block addressBlock ;
571
+ final Block inputBlock ;
551
572
552
- Block addressBlock = new Block ();
553
- Block inputBlock = new Block ();
573
+ private FillBlock (BlockPool pool ) {
574
+ R = pool .allocate ();
575
+ Z = pool .allocate ();
576
+
577
+ addressBlock = pool .allocate ();
578
+ inputBlock = pool .allocate ();
579
+ }
580
+
581
+ public void deallocate (BlockPool pool ) {
582
+ pool .deallocate (addressBlock );
583
+ pool .deallocate (inputBlock );
584
+ pool .deallocate (R );
585
+ pool .deallocate (Z );
586
+ }
554
587
555
588
private void applyBlake ()
556
589
{
@@ -611,14 +644,14 @@ private void fillBlockWithXor(Block X, Block Y, Block currentBlock)
611
644
}
612
645
}
613
646
614
- private static class Block
647
+ public static class Block
615
648
{
616
649
private static final int SIZE = ARGON2_QWORDS_IN_BLOCK ;
617
650
618
651
/* 128 * 8 Byte QWords */
619
652
private final long [] v ;
620
653
621
- private Block ()
654
+ public Block ()
622
655
{
623
656
v = new long [SIZE ];
624
657
}
0 commit comments