Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid ByteBuffer#asReadOnlyBuffer() #29

Merged
merged 2 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ void encryptChunk(ByteBuffer cleartextChunk, ByteBuffer ciphertextChunk, long ch
int bytesEncrypted = cipher.doFinal(cleartextChunk, ciphertextChunk);

// mac:
final ByteBuffer ciphertextBuf = ciphertextChunk.asReadOnlyBuffer();
ciphertextBuf.position(NONCE_SIZE).limit(NONCE_SIZE + bytesEncrypted);
byte[] authenticationCode = calcChunkMac(headerNonce, chunkNumber, nonce, ciphertextBuf);
ByteBuffer nonceAndPayload = ciphertextChunk.duplicate();
nonceAndPayload.flip();
byte[] authenticationCode = calcChunkMac(headerNonce, chunkNumber, nonceAndPayload);
assert authenticationCode.length == MAC_SIZE;
ciphertextChunk.put(authenticationCode);
} catch (ShortBufferException e) {
Expand All @@ -134,12 +134,10 @@ void decryptChunk(ByteBuffer ciphertextChunk, ByteBuffer cleartextChunk, Destroy
try (DestroyableSecretKey fk = fileKey.copy()) {
// nonce:
final byte[] nonce = new byte[NONCE_SIZE];
final ByteBuffer chunkNonceBuf = ciphertextChunk.asReadOnlyBuffer();
chunkNonceBuf.position(0).limit(NONCE_SIZE);
chunkNonceBuf.get(nonce);
ciphertextChunk.get(nonce, 0, NONCE_SIZE);

// payload:
final ByteBuffer payloadBuf = ciphertextChunk.asReadOnlyBuffer();
final ByteBuffer payloadBuf = ciphertextChunk.duplicate();
payloadBuf.position(NONCE_SIZE).limit(ciphertextChunk.limit() - MAC_SIZE);

// payload:
Expand All @@ -157,37 +155,30 @@ void decryptChunk(ByteBuffer ciphertextChunk, ByteBuffer cleartextChunk, Destroy
boolean checkChunkMac(byte[] headerNonce, long chunkNumber, ByteBuffer chunkBuf) {
assert chunkBuf.remaining() >= NONCE_SIZE + MAC_SIZE;

// get three components: nonce + payload + mac
final ByteBuffer chunkNonceBuf = chunkBuf.asReadOnlyBuffer();
chunkNonceBuf.position(0).limit(NONCE_SIZE);
final ByteBuffer payloadBuf = chunkBuf.asReadOnlyBuffer();
payloadBuf.position(NONCE_SIZE).limit(chunkBuf.limit() - MAC_SIZE);
final ByteBuffer expectedMacBuf = chunkBuf.asReadOnlyBuffer();
// get nonce + payload
final ByteBuffer nonceAndPayload = chunkBuf.duplicate();
nonceAndPayload.position(0).limit(chunkBuf.limit() - MAC_SIZE);
final ByteBuffer expectedMacBuf = chunkBuf.duplicate();
expectedMacBuf.position(chunkBuf.limit() - MAC_SIZE);

// get nonce:
final byte[] chunkNonce = new byte[NONCE_SIZE];
chunkNonceBuf.get(chunkNonce);

// get expected MAC:
final byte[] expectedMac = new byte[MAC_SIZE];
expectedMacBuf.get(expectedMac);

// get actual MAC:
final byte[] calculatedMac = calcChunkMac(headerNonce, chunkNumber, chunkNonce, payloadBuf);
final byte[] calculatedMac = calcChunkMac(headerNonce, chunkNumber, nonceAndPayload);

// time-constant equality check of two MACs:
return MessageDigest.isEqual(expectedMac, calculatedMac);
}

private byte[] calcChunkMac(byte[] headerNonce, long chunkNumber, byte[] chunkNonce, ByteBuffer ciphertext) {
private byte[] calcChunkMac(byte[] headerNonce, long chunkNumber, ByteBuffer nonceAndCiphertext) {
try (DestroyableSecretKey mk = masterkey.getMacKey()) {
final byte[] chunkNumberBigEndian = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).order(ByteOrder.BIG_ENDIAN).putLong(chunkNumber).array();
final Mac mac = MacSupplier.HMAC_SHA256.withKey(mk);
mac.update(headerNonce);
mac.update(chunkNumberBigEndian);
mac.update(chunkNonce);
mac.update(ciphertext);
mac.update(nonceAndCiphertext);
return mac.doFinal();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public FileHeader decryptHeader(ByteBuffer ciphertextHeaderBuf) throws Authentic
if (ciphertextHeaderBuf.remaining() < FileHeaderImpl.SIZE) {
throw new IllegalArgumentException("Malformed ciphertext header");
}
ByteBuffer buf = ciphertextHeaderBuf.asReadOnlyBuffer();
ByteBuffer buf = ciphertextHeaderBuf.duplicate();
byte[] nonce = new byte[FileHeaderImpl.NONCE_LEN];
buf.position(FileHeaderImpl.NONCE_POS);
buf.get(nonce);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,10 @@ void decryptChunk(ByteBuffer ciphertextChunk, ByteBuffer cleartextChunk, long ch
try (DestroyableSecretKey fk = fileKey.copy()) {
// nonce:
final byte[] nonce = new byte[GCM_NONCE_SIZE];
final ByteBuffer chunkNonceBuf = ciphertextChunk.asReadOnlyBuffer();
chunkNonceBuf.position(0).limit(GCM_NONCE_SIZE);
chunkNonceBuf.get(nonce);
ciphertextChunk.get(nonce, 0, GCM_NONCE_SIZE);

// payload:
final ByteBuffer payloadBuf = ciphertextChunk.asReadOnlyBuffer();
final ByteBuffer payloadBuf = ciphertextChunk.duplicate();
payloadBuf.position(GCM_NONCE_SIZE);
assert payloadBuf.remaining() >= GCM_TAG_SIZE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public FileHeader decryptHeader(ByteBuffer ciphertextHeaderBuf) throws Authentic
if (ciphertextHeaderBuf.remaining() < FileHeaderImpl.SIZE) {
throw new IllegalArgumentException("Malformed ciphertext header");
}
ByteBuffer buf = ciphertextHeaderBuf.asReadOnlyBuffer();
ByteBuffer buf = ciphertextHeaderBuf.duplicate();
byte[] nonce = new byte[FileHeaderImpl.NONCE_LEN];
buf.position(FileHeaderImpl.NONCE_POS);
buf.get(nonce);
Expand Down