mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 19:59:05 +01:00
Use XSalsa20-Poly1305 instead of AES-GCM. #111
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
package org.briarproject.crypto;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.MAC_LENGTH;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import org.briarproject.api.crypto.SecretKey;
|
||||
import org.spongycastle.crypto.DataLengthException;
|
||||
import org.spongycastle.crypto.InvalidCipherTextException;
|
||||
import org.spongycastle.crypto.engines.AESLightEngine;
|
||||
import org.spongycastle.crypto.modes.AEADBlockCipher;
|
||||
import org.spongycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.spongycastle.crypto.modes.gcm.BasicGCMMultiplier;
|
||||
import org.spongycastle.crypto.params.AEADParameters;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
class AuthenticatedCipherImpl implements AuthenticatedCipher {
|
||||
|
||||
private final AEADBlockCipher cipher;
|
||||
|
||||
AuthenticatedCipherImpl() {
|
||||
cipher = new GCMBlockCipher(new AESLightEngine(),
|
||||
new BasicGCMMultiplier());
|
||||
}
|
||||
|
||||
public int process(byte[] input, int inputOff, int len, byte[] output,
|
||||
int outputOff) throws GeneralSecurityException {
|
||||
int processed = 0;
|
||||
if (len != 0) {
|
||||
processed = cipher.processBytes(input, inputOff, len, output,
|
||||
outputOff);
|
||||
}
|
||||
try {
|
||||
return processed + cipher.doFinal(output, outputOff + processed);
|
||||
} catch (DataLengthException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
} catch (InvalidCipherTextException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void init(boolean encrypt, SecretKey key, byte[] iv)
|
||||
throws GeneralSecurityException {
|
||||
KeyParameter k = new KeyParameter(key.getBytes());
|
||||
// Authenticate the IV by passing it as additional authenticated data
|
||||
AEADParameters params = new AEADParameters(k, MAC_LENGTH * 8, iv, iv);
|
||||
try {
|
||||
cipher.init(encrypt, params);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int getMacBytes() {
|
||||
return MAC_LENGTH;
|
||||
}
|
||||
}
|
||||
@@ -55,8 +55,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
private static final int AGREEMENT_KEY_PAIR_BITS = 256;
|
||||
private static final int SIGNATURE_KEY_PAIR_BITS = 256;
|
||||
private static final int STORAGE_IV_BYTES = 16; // 128 bits
|
||||
private static final int PBKDF_SALT_BYTES = 16; // 128 bits
|
||||
private static final int STORAGE_IV_BYTES = 24; // 196 bits
|
||||
private static final int PBKDF_SALT_BYTES = 32; // 256 bits
|
||||
private static final int PBKDF_TARGET_MILLIS = 500;
|
||||
private static final int PBKDF_SAMPLES = 30;
|
||||
|
||||
@@ -325,7 +325,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[] encryptWithPassword(byte[] input, String password) {
|
||||
AuthenticatedCipher cipher = new AuthenticatedCipherImpl();
|
||||
AuthenticatedCipher cipher = new XSalsa20Poly1305AuthenticatedCipher();
|
||||
int macBytes = cipher.getMacBytes();
|
||||
// Generate a random salt
|
||||
byte[] salt = new byte[PBKDF_SALT_BYTES];
|
||||
@@ -355,7 +355,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[] decryptWithPassword(byte[] input, String password) {
|
||||
AuthenticatedCipher cipher = new AuthenticatedCipherImpl();
|
||||
AuthenticatedCipher cipher = new XSalsa20Poly1305AuthenticatedCipher();
|
||||
int macBytes = cipher.getMacBytes();
|
||||
// The input contains the salt, iterations, IV, ciphertext and MAC
|
||||
if (input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + macBytes)
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
package org.briarproject.crypto;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.crypto.CryptoExecutor;
|
||||
import org.briarproject.api.crypto.PasswordStrengthEstimator;
|
||||
import org.briarproject.api.crypto.StreamDecrypterFactory;
|
||||
import org.briarproject.api.crypto.StreamEncrypterFactory;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -11,15 +19,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.crypto.CryptoExecutor;
|
||||
import org.briarproject.api.crypto.PasswordStrengthEstimator;
|
||||
import org.briarproject.api.crypto.StreamDecrypterFactory;
|
||||
import org.briarproject.api.crypto.StreamEncrypterFactory;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
public class CryptoModule extends AbstractModule {
|
||||
|
||||
@@ -42,7 +42,8 @@ public class CryptoModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AuthenticatedCipher.class).to(AuthenticatedCipherImpl.class);
|
||||
bind(AuthenticatedCipher.class).to(
|
||||
XSalsa20Poly1305AuthenticatedCipher.class);
|
||||
bind(CryptoComponent.class).to(
|
||||
CryptoComponentImpl.class).in(Singleton.class);
|
||||
bind(PasswordStrengthEstimator.class).to(
|
||||
|
||||
@@ -24,7 +24,8 @@ import static org.briarproject.api.transport.TransportConstants.MAC_LENGTH;
|
||||
* <li>http://cr.yp.to/highspeed/naclcrypto-20090310.pdf</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class XSalsa20Poly1305AC implements AuthenticatedCipher {
|
||||
public class XSalsa20Poly1305AuthenticatedCipher
|
||||
implements AuthenticatedCipher {
|
||||
|
||||
/** Length of the padding to be used to generate the Poly1305 key */
|
||||
private static final int SUBKEY_LENGTH = 32;
|
||||
@@ -34,13 +35,14 @@ public class XSalsa20Poly1305AC implements AuthenticatedCipher {
|
||||
|
||||
private boolean encrypting;
|
||||
|
||||
XSalsa20Poly1305AC() {
|
||||
XSalsa20Poly1305AuthenticatedCipher() {
|
||||
xSalsa20Engine = new XSalsa20Engine();
|
||||
poly1305 = new Poly1305();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(boolean encrypt, SecretKey key, byte[] iv) throws GeneralSecurityException {
|
||||
public void init(boolean encrypt, SecretKey key, byte[] iv)
|
||||
throws GeneralSecurityException {
|
||||
encrypting = encrypt;
|
||||
KeyParameter k = new KeyParameter(key.getBytes());
|
||||
ParametersWithIV params = new ParametersWithIV(k, iv);
|
||||
@@ -52,12 +54,10 @@ public class XSalsa20Poly1305AC implements AuthenticatedCipher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int process(byte[] input, int inputOff, int len, byte[] output, int outputOff) throws GeneralSecurityException {
|
||||
if (len == 0)
|
||||
return 0;
|
||||
else if (!encrypting && len < MAC_LENGTH)
|
||||
public int process(byte[] input, int inputOff, int len, byte[] output,
|
||||
int outputOff) throws GeneralSecurityException {
|
||||
if (!encrypting && len < MAC_LENGTH)
|
||||
throw new GeneralSecurityException("Invalid MAC");
|
||||
|
||||
try {
|
||||
// Generate the Poly1305 subkey from an empty array
|
||||
byte[] zero = new byte[SUBKEY_LENGTH];
|
||||
@@ -100,7 +100,7 @@ public class XSalsa20Poly1305AC implements AuthenticatedCipher {
|
||||
throw new GeneralSecurityException("Invalid MAC");
|
||||
}
|
||||
|
||||
// Invert the stream encryption
|
||||
// Apply or invert the stream encryption
|
||||
int processed = xSalsa20Engine.processBytes(
|
||||
input, encrypting ? inputOff : inputOff + MAC_LENGTH,
|
||||
encrypting ? len : len - MAC_LENGTH,
|
||||
Reference in New Issue
Block a user