Skip to content

Commit 46677df

Browse files
committed
Merge branch 'main' of gitlab.cryptoworkshop.com:root/bc-java
2 parents 57c022f + 4d36782 commit 46677df

15 files changed

Lines changed: 379 additions & 494 deletions

File tree

‎core/src/main/java/org/bouncycastle/crypto/macs/Zuc128Mac.java‎

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111
public final class Zuc128Mac
1212
implements Mac
1313
{
14-
/**
15-
* The Maximum Bit Mask.
16-
*/
17-
private static final int TOPBIT = 0x80;
18-
1914
/**
2015
* The Zuc128 Engine.
2116
*/
@@ -115,17 +110,21 @@ public void update(final byte in)
115110
/* shift for next byte */
116111
shift4NextByte();
117112

118-
/* Loop through the bits */
113+
/*
114+
* Loop through the bits, accumulating each bit's contribution branchlessly:
115+
* the mask -bit is all-ones for a set bit and zero for a clear one, so the
116+
* keyStream window is XORed in either way and the amount of work done does
117+
* not depend on the message. Branching on the message bit made the time taken
118+
* proportional to its Hamming weight.
119+
*/
119120
final int bitBase = theByteIndex * 8; //Byte.SIZE;
120-
for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
121+
int acc = 0;
122+
for (int bitNo = 0; bitNo < 8; bitNo++) //Byte.SIZE
121123
{
122-
/* If the bit is set */
123-
if ((in & bitMask) != 0)
124-
{
125-
/* update theMac */
126-
updateMac(bitBase + bitNo);
127-
}
124+
final int bit = (in >>> (7 - bitNo)) & 1;
125+
acc ^= getKeyStreamWord(bitBase + bitNo) & -bit;
128126
}
127+
theMac ^= acc;
129128
}
130129

131130
/**
@@ -144,17 +143,6 @@ private void shift4NextByte()
144143
}
145144
}
146145

147-
/**
148-
* Update the Mac.
149-
*
150-
* @param bitNo the bit number
151-
*/
152-
private void updateMac(final int bitNo)
153-
{
154-
/* Update the Mac */
155-
theMac ^= getKeyStreamWord(bitNo);
156-
}
157-
158146
/**
159147
* Obtain the keyStreamWord.
160148
*

‎core/src/main/java/org/bouncycastle/crypto/macs/Zuc256Mac.java‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111
public final class Zuc256Mac
1212
implements Mac
1313
{
14-
/**
15-
* The Maximum Bit Mask.
16-
*/
17-
private static final int TOPBIT = 0x80;
18-
1914
/**
2015
* The Zuc256 Engine.
2116
*/
@@ -128,15 +123,20 @@ public void update(final byte in)
128123
/* shift for next byte */
129124
shift4NextByte();
130125

131-
/* Loop through the bits */
126+
/*
127+
* Loop through the bits, accumulating each bit's contribution branchlessly:
128+
* the mask -bit is all-ones for a set bit and zero for a clear one, so every
129+
* mac word is XORed either way and the amount of work done does not depend on
130+
* the message. Branching on the message bit made the time taken proportional
131+
* to its Hamming weight.
132+
*/
132133
final int bitBase = theByteIndex * 8; //Byte.SIZE;
133-
for (int bitMask = TOPBIT, bitNo = 0; bitMask > 0; bitMask >>= 1, bitNo++)
134+
for (int bitNo = 0; bitNo < 8; bitNo++) //Byte.SIZE
134135
{
135-
/* If the bit is set */
136-
if ((in & bitMask) != 0)
136+
final int mask = -((in >>> (7 - bitNo)) & 1);
137+
for (int wordNo = 0; wordNo < theMac.length; wordNo++)
137138
{
138-
/* update theMac */
139-
updateMac(bitBase + bitNo);
139+
theMac[wordNo] ^= getKeyStreamWord(wordNo, bitBase + bitNo) & mask;
140140
}
141141
}
142142
}

‎docs/releasenotes.html‎

Lines changed: 3 additions & 0 deletions
Large diffs are not rendered by default.

‎pg/src/main/java/org/bouncycastle/gpg/keybox/CertificateBlob.java‎

Lines changed: 4 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.bouncycastle.gpg.keybox;
22

33
import java.io.IOException;
4-
import java.util.ArrayList;
5-
import java.util.List;
64

75
/**
86
* A PGP blob holds key material.
@@ -13,163 +11,19 @@ public class CertificateBlob
1311
private CertificateBlob(int base, long length,
1412
BlobType type,
1513
int version,
16-
int blobFlags,
17-
int keyNumber,
18-
List<KeyInformation> keyInformation,
19-
byte[] serialNumber,
20-
int numberOfUserIDs,
21-
List<UserID> userIds,
22-
int numberOfSignatures,
23-
List<Long> expirationTime,
24-
int assignedOwnerTrust,
25-
int allValidity,
26-
long recheckAfter,
27-
long newestTimestamp,
28-
long blobCreatedAt,
29-
byte[] keyBytes,
30-
byte[] reserveBytes,
31-
byte[] sha1Checksum)
14+
KeyBlobContent content)
3215
{
33-
super(base, length, type, version, blobFlags, keyNumber,
34-
keyInformation, serialNumber, numberOfUserIDs, userIds, numberOfSignatures,
35-
expirationTime, assignedOwnerTrust, allValidity, recheckAfter, newestTimestamp, blobCreatedAt,
36-
keyBytes, reserveBytes, sha1Checksum);
16+
super(base, length, type, version, content);
3717
}
3818

3919

4020
static Blob parseContent(int base, long length, BlobType type, int version, KeyBoxByteBuffer buffer, BlobVerifier blobVerifier)
4121
throws IOException
4222
{
4323

44-
//
45-
// u32 Length of this blob (including these 4 bytes)
46-
// byte Blob type
47-
// 2 = OpenPGP
48-
// 3 = X509
49-
// byte Version number of this blob type
50-
// 1 = The only defined value
51-
//
24+
KeyBlobContent content = KeyBlobContent.parse(base, length, buffer, blobVerifier);
5225

53-
54-
//
55-
// Take checksum first.
56-
//
57-
verifyDigest(base, length, buffer, blobVerifier);
58-
59-
60-
int blobFlags = buffer.u16(); // u16 Blob flags
61-
long keyBlockOffset = buffer.u32(); // u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
62-
long keyBlockLength = buffer.u32(); // u32 and its length
63-
64-
int keyNumber = buffer.u16(); // u16 number of keys (at least 1!) [X509: always 1]
65-
66-
67-
// This value defines the length of the space reserved for the AdditionalKeyInformation
68-
int keyInformationStructureSize = buffer.u16(); // u16 size of additional key information
69-
70-
//
71-
// Load the additional key information.
72-
//
73-
List<KeyInformation> keyInformation = new ArrayList<KeyInformation>();
74-
75-
for (int t = keyNumber - 1; t >= 0; t--)
76-
{
77-
keyInformation.add(KeyInformation.getInstance(buffer, keyInformationStructureSize, base));
78-
}
79-
80-
int sizeOfSerialNumber = buffer.u16(); // size of serialnumber(may be zero)
81-
82-
byte[] serialNumber = buffer.bN(sizeOfSerialNumber);
83-
// buffer.bN(serialNumber); // n u16 (see above) bytes of serial number
84-
85-
int numberOfUserIDs = buffer.u16(); // u16 number of user IDs
86-
buffer.u16(); // size of additional user ID information
87-
88-
//
89-
// User IDS.
90-
//
91-
List<UserID> userIds = new ArrayList<UserID>();
92-
long totalUserIdLength = 0;
93-
for (int t = numberOfUserIDs - 1; t >= 0; t--)
94-
{
95-
UserID userID = UserID.getInstance(buffer, base);
96-
// Bound the cumulative user-ID data by the blob length: each entry copies an
97-
// attacker-controlled slice of the blob, so an inflated user-ID count with each entry
98-
// pointing at (almost) the whole blob would otherwise retain ~bufferSize^2 bytes.
99-
totalUserIdLength += userID.getLengthOfUserId();
100-
if (totalUserIdLength > length)
101-
{
102-
throw new IllegalStateException("userID data exceeds blob length");
103-
}
104-
userIds.add(userID);
105-
}
106-
107-
int numberOfSignatures = buffer.u16();
108-
buffer.u16();
109-
110-
111-
List<Long> signatureExpirationTime = new ArrayList<Long>();
112-
for (int t = numberOfSignatures - 1; t >= 0; t--)
113-
{
114-
signatureExpirationTime.add(buffer.u32());
115-
}
116-
117-
int assignedOwnerTrust = buffer.u8(); // din.read();
118-
int allValidity = buffer.u8();
119-
120-
buffer.u16(); // RFU
121-
long recheckAfter = buffer.u32();
122-
long newestTimestamp = buffer.u32();
123-
long blobCreatedAt = buffer.u32();
124-
125-
long sizeOfReservedSpace = buffer.u32();
126-
127-
if (sizeOfReservedSpace > buffer.remaining())
128-
{
129-
throw new IllegalStateException("sizeOfReservedSpace exceeds content remaining in buffer");
130-
}
131-
132-
// Arbitrary reserved space, that may hold X509 V3 certificate IDs.!
133-
byte[] reserveData = buffer.bN((int)sizeOfReservedSpace); // Reserved space of size NRES for future use.
134-
// buffer.bN(reserveData);
135-
136-
137-
//
138-
// Key block is loaded based from the start of the blob rather than
139-
//
140-
141-
byte[] keyData = buffer.rangeOf(
142-
(int)(base + keyBlockOffset),
143-
(int)(base + keyBlockOffset + keyBlockLength)); // Defined near top of structure..
144-
145-
146-
//
147-
// Reserve space.
148-
//
149-
int dataSize = (int)(length - (buffer.position() - base) - 20);
150-
byte[] data = buffer.bN(dataSize);
151-
152-
153-
byte[] sha1Checksum = buffer.rangeOf((int)(base + length - 20), (int)(base + length));
154-
buffer.consume(sha1Checksum.length);
155-
156-
return new CertificateBlob(base, length,
157-
type,
158-
version,
159-
blobFlags,
160-
keyNumber,
161-
keyInformation,
162-
serialNumber,
163-
numberOfUserIDs,
164-
userIds,
165-
numberOfSignatures,
166-
signatureExpirationTime,
167-
assignedOwnerTrust,
168-
allValidity,
169-
recheckAfter,
170-
newestTimestamp,
171-
blobCreatedAt,
172-
keyData, reserveData, sha1Checksum);
26+
return new CertificateBlob(base, length, type, version, content);
17327
}
17428

17529
/**

0 commit comments

Comments
 (0)