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 ;
@@ -98,6 +102,7 @@ public int generateBytes(byte[] password, byte[] out, int outOff, int outLen)
98
102
99
103
byte [] tmpBlockBytes = new byte [ARGON2_BLOCK_SIZE ];
100
104
105
+ initMemory (memoryBlocks );
101
106
initialize (tmpBlockBytes , password , outLen );
102
107
fillMemoryBlocks ();
103
108
digest (tmpBlockBytes , out , outOff , outLen );
@@ -118,17 +123,18 @@ private void reset()
118
123
Block b = memory [i ];
119
124
if (null != b )
120
125
{
121
- b . clear ( );
126
+ pool . deallocate ( b );
122
127
}
123
128
}
124
129
}
130
+ memory = null ;
125
131
}
126
132
127
133
private void doInit (Argon2Parameters parameters )
128
134
{
129
135
/* 2. Align memory size */
130
136
/* Minimum memoryBlocks = 8L blocks, where L is the number of lanes */
131
- int memoryBlocks = parameters .getMemory ();
137
+ memoryBlocks = parameters .getMemory ();
132
138
133
139
if (memoryBlocks < 2 * Argon2BytesGenerator .ARGON2_SYNC_POINTS * parameters .getLanes ())
134
140
{
@@ -141,7 +147,11 @@ private void doInit(Argon2Parameters parameters)
141
147
/* Ensure that all segments have equal length */
142
148
memoryBlocks = segmentLength * (parameters .getLanes () * Argon2BytesGenerator .ARGON2_SYNC_POINTS );
143
149
144
- initMemory (memoryBlocks );
150
+ pool = parameters .getBlockPool ();
151
+ if (pool == null ) {
152
+ // if no pool is provided hold on to enough blocks for the primary memory
153
+ pool = new FixedBlockPool (memoryBlocks );
154
+ }
145
155
}
146
156
147
157
private void initMemory (int memoryBlocks )
@@ -150,13 +160,13 @@ private void initMemory(int memoryBlocks)
150
160
151
161
for (int i = 0 ; i < memory .length ; i ++)
152
162
{
153
- memory [i ] = new Block ();
163
+ memory [i ] = pool . allocate ();
154
164
}
155
165
}
156
166
157
167
private void fillMemoryBlocks ()
158
168
{
159
- FillBlock filler = new FillBlock ();
169
+ FillBlock filler = new FillBlock (pool );
160
170
Position position = new Position ();
161
171
for (int pass = 0 ; pass < parameters .getIterations (); ++pass )
162
172
{
@@ -174,6 +184,7 @@ private void fillMemoryBlocks()
174
184
}
175
185
}
176
186
}
187
+ filler .deallocate (pool );
177
188
}
178
189
179
190
private void fillSegment (FillBlock filler , Position position )
@@ -548,16 +559,31 @@ private void fillFirstBlocks(byte[] tmpBlockBytes, byte[] initialHashWithZeros)
548
559
549
560
private long intToLong (int x )
550
561
{
551
- return ( long )( x & M32L ) ;
562
+ return x & M32L ;
552
563
}
553
564
554
565
private static class FillBlock
555
566
{
556
- Block R = new Block ();
557
- Block Z = new Block ();
567
+ final Block R ;
568
+ final Block Z ;
569
+
570
+ final Block addressBlock ;
571
+ final Block inputBlock ;
558
572
559
- Block addressBlock = new Block ();
560
- 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
+ }
561
587
562
588
private void applyBlake ()
563
589
{
@@ -618,14 +644,14 @@ private void fillBlockWithXor(Block X, Block Y, Block currentBlock)
618
644
}
619
645
}
620
646
621
- private static class Block
647
+ public static class Block
622
648
{
623
649
private static final int SIZE = ARGON2_QWORDS_IN_BLOCK ;
624
650
625
651
/* 128 * 8 Byte QWords */
626
652
private final long [] v ;
627
653
628
- private Block ()
654
+ public Block ()
629
655
{
630
656
v = new long [SIZE ];
631
657
}
0 commit comments