Skip to content

Commit 119071a

Browse files
committed
Refactoring in generators
1 parent 0aa6f0a commit 119071a

3 files changed

Lines changed: 54 additions & 61 deletions

File tree

core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.bouncycastle.crypto.DerivationParameters;
1414
import org.bouncycastle.crypto.Digest;
1515
import org.bouncycastle.crypto.OutputLengthException;
16+
import org.bouncycastle.crypto.io.DigestOutputStream;
1617
import org.bouncycastle.util.Pack;
1718

1819
/**
@@ -58,61 +59,54 @@ public int generateBytes(byte[] out, int outOff, int len)
5859

5960
digest.reset();
6061

61-
long oBytes = len;
62-
int outLen = digest.getDigestSize();
62+
int outputLength = len;
63+
int digestSize = digest.getDigestSize();
6364

6465
// NOTE: This limit isn't reachable for current array lengths
65-
if (oBytes > ((1L << 32) - 1) * outLen)
66+
if (outputLength > ((1L << 32) - 1) * digestSize)
6667
{
6768
throw new IllegalArgumentException("Output length too large");
6869
}
6970

70-
int cThreshold = (int)((oBytes + outLen - 1) / outLen);
71+
int counter32 = 0;
72+
byte[] counterOctets = new byte[4];
7173

72-
byte[] dig = new byte[digest.getDigestSize()];
74+
ASN1OctetString counter = DEROctetString.withContents(counterOctets);
75+
KeySpecificInfo keyInfo = new KeySpecificInfo(algorithm, counter);
76+
ASN1OctetString partyAInfo = DEROctetString.withContentsOptional(extraInfo);
77+
ASN1OctetString suppPubInfo = DEROctetString.withContents(Pack.intToBigEndian(keySize));
78+
OtherInfo otherInfo = new OtherInfo(keyInfo, partyAInfo, suppPubInfo);
7379

74-
int counter32 = 1;
80+
DigestOutputStream digestSink = new DigestOutputStream(digest);
7581

76-
for (int i = 0; i < cThreshold; i++)
82+
while (len > 0)
7783
{
7884
digest.update(z, 0, z.length);
7985

80-
// KeySpecificInfo
81-
ASN1OctetString counter = DEROctetString.withContents(Pack.intToBigEndian(counter32));
82-
KeySpecificInfo keyInfo = new KeySpecificInfo(algorithm, counter);
83-
84-
// OtherInfo
85-
ASN1OctetString partyAInfo = DEROctetString.withContentsOptional(extraInfo);
86-
ASN1OctetString suppPubInfo = DEROctetString.withContents(Pack.intToBigEndian(keySize));
87-
OtherInfo otherInfo = new OtherInfo(keyInfo, partyAInfo, suppPubInfo);
88-
8986
try
9087
{
91-
byte[] other = otherInfo.getEncoded(ASN1Encoding.DER);
92-
93-
digest.update(other, 0, other.length);
88+
// NOTE: Modify counterOctets in-situ since counter is private to this method
89+
Pack.intToBigEndian(++counter32, counterOctets);
90+
otherInfo.encodeTo(digestSink, ASN1Encoding.DER);
9491
}
9592
catch (IOException e)
9693
{
9794
throw new IllegalArgumentException("unable to encode parameter info: " + e.getMessage());
9895
}
9996

100-
digest.doFinal(dig, 0);
101-
102-
if (len > outLen)
103-
{
104-
System.arraycopy(dig, 0, out, outOff, outLen);
105-
outOff += outLen;
106-
len -= outLen;
107-
}
108-
else
97+
if (len < digestSize)
10998
{
110-
System.arraycopy(dig, 0, out, outOff, len);
99+
byte[] tmp = new byte[digestSize];
100+
digest.doFinal(tmp, 0);
101+
System.arraycopy(tmp, 0, out, outOff, len);
102+
break;
111103
}
112104

113-
counter32++;
105+
digest.doFinal(out, outOff);
106+
outOff += digestSize;
107+
len -= digestSize;
114108
}
115109

116-
return (int)oBytes;
110+
return outputLength;
117111
}
118112
}

core/src/main/java/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -84,56 +84,47 @@ public int generateBytes(byte[] out, int outOff, int len) throws DataLengthExcep
8484
throw new OutputLengthException("output buffer too small");
8585
}
8686

87-
long oBytes = len;
88-
int outLen = digest.getDigestSize();
87+
digest.reset();
88+
89+
int outputLength = len;
90+
int digestSize = digest.getDigestSize();
8991

9092
// NOTE: This limit isn't reachable for current array lengths
91-
if (oBytes > ((1L << 32) - 1) * outLen)
93+
if (outputLength > ((1L << 32) - 1) * digestSize)
9294
{
9395
throw new IllegalArgumentException("Output length too large");
9496
}
9597

96-
int cThreshold = (int)((oBytes + outLen - 1) / outLen);
97-
98-
byte[] dig = new byte[digest.getDigestSize()];
99-
98+
int counter32 = counterStart;
10099
byte[] C = new byte[4];
101-
Pack.intToBigEndian(counterStart, C, 0);
102100

103-
int counterBase = counterStart & ~0xFF;
104-
105-
for (int i = 0; i < cThreshold; i++)
101+
while (len > 0)
106102
{
103+
Pack.intToBigEndian(counter32, C);
104+
107105
digest.update(shared, 0, shared.length);
108-
digest.update(C, 0, C.length);
106+
digest.update(C, 0, 4);
109107

110108
if (iv != null)
111109
{
112110
digest.update(iv, 0, iv.length);
113111
}
114112

115-
digest.doFinal(dig, 0);
116-
117-
if (len > outLen)
113+
if (len < digestSize)
118114
{
119-
System.arraycopy(dig, 0, out, outOff, outLen);
120-
outOff += outLen;
121-
len -= outLen;
122-
}
123-
else
124-
{
125-
System.arraycopy(dig, 0, out, outOff, len);
115+
byte[] tmp = new byte[digestSize];
116+
digest.doFinal(tmp, 0);
117+
System.arraycopy(tmp, 0, out, outOff, len);
118+
break;
126119
}
127120

128-
if (++C[3] == 0)
129-
{
130-
counterBase += 0x100;
131-
Pack.intToBigEndian(counterBase, C, 0);
132-
}
133-
}
121+
digest.doFinal(out, outOff);
122+
outOff += digestSize;
123+
len -= digestSize;
134124

135-
digest.reset();
125+
++counter32;
126+
}
136127

137-
return (int)oBytes;
128+
return outputLength;
138129
}
139130
}

core/src/main/java/org/bouncycastle/util/Pack.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ public static byte[] intToBigEndian(int n)
6464
return bs;
6565
}
6666

67+
public static void intToBigEndian(int n, byte[] bs)
68+
{
69+
bs[0] = (byte)(n >>> 24);
70+
bs[1] = (byte)(n >>> 16);
71+
bs[2] = (byte)(n >>> 8);
72+
bs[3] = (byte)(n);
73+
}
74+
6775
public static void intToBigEndian(int n, byte[] bs, int off)
6876
{
6977
bs[off] = (byte)(n >>> 24);

0 commit comments

Comments
 (0)