diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/EciesHelper.java b/src/main/java/org/cryptomator/ui/keyloading/hub/EciesHelper.java index a1636ea3a..b7dac36ba 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/EciesHelper.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/EciesHelper.java @@ -1,6 +1,7 @@ package org.cryptomator.ui.keyloading.hub; import com.google.common.base.Preconditions; +import com.google.common.io.BaseEncoding; import org.cryptomator.cryptolib.api.Masterkey; import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; import org.cryptomator.cryptolib.common.CipherSupplier; @@ -13,6 +14,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.spec.GCMParameterSpec; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.security.DigestException; import java.security.InvalidKeyException; import java.security.KeyPair; @@ -26,16 +28,17 @@ import java.util.Arrays; class EciesHelper { + private static final int GCM_KEY_SIZE = 32; private static final int GCM_TAG_SIZE = 16; private static final int GCM_NONCE_SIZE = 12; // 96 bit IVs strongly recommended for GCM private EciesHelper() {} public static Masterkey decryptMasterkey(KeyPair deviceKey, EciesParams eciesParams) throws MasterkeyLoadingFailedException { - var sharedSecret = ecdhAndKdf(deviceKey.getPrivate(), eciesParams.getEphemeralPublicKey(), 44); + var sharedSecret = ecdhAndKdf(deviceKey.getPrivate(), eciesParams.getEphemeralPublicKey(), GCM_KEY_SIZE + GCM_NONCE_SIZE); var cleartext = new byte[0]; - try (var kek = new DestroyableSecretKey(sharedSecret, 0, 32, "AES")) { - var nonce = Arrays.copyOfRange(sharedSecret, 32, GCM_NONCE_SIZE); + try (var kek = new DestroyableSecretKey(sharedSecret, 0, GCM_KEY_SIZE, "AES")) { + var nonce = Arrays.copyOfRange(sharedSecret, GCM_KEY_SIZE, GCM_KEY_SIZE + GCM_NONCE_SIZE); var cipher = CipherSupplier.AES_GCM.forDecryption(kek, new GCMParameterSpec(GCM_TAG_SIZE * Byte.SIZE, nonce)); cleartext = cipher.doFinal(eciesParams.getCiphertext()); return new Masterkey(cleartext); @@ -78,6 +81,7 @@ class EciesHelper { /** * Performs ANSI-X9.63-KDF with SHA-256 * @param sharedSecret A shared secret + * @param sharedInfo Additional authenticated data * @param keyDataLen Desired key length (in bytes) * @return key data */ @@ -91,6 +95,7 @@ class EciesHelper { assert keyDataLen < (2L << 32 - 1) * hashLen : "keyDataLen larger than hashLen × (2^32 − 1)"; ByteBuffer counter = ByteBuffer.allocate(Integer.BYTES); + assert ByteOrder.BIG_ENDIAN.equals(counter.order()); int n = (keyDataLen + hashLen - 1) / hashLen; byte[] buffer = new byte[n * hashLen]; try {