mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Fixed some key derivation bugs and removed an unnecessary argument.
CryptoComponentImpl needs some unit tests.
This commit is contained in:
@@ -19,7 +19,7 @@ public interface CryptoComponent {
|
|||||||
byte[][] deriveInitialSecrets(byte[] ourPublicKey, byte[] theirPublicKey,
|
byte[][] deriveInitialSecrets(byte[] ourPublicKey, byte[] theirPublicKey,
|
||||||
PrivateKey ourPrivateKey, int invitationCode, boolean initiator);
|
PrivateKey ourPrivateKey, int invitationCode, boolean initiator);
|
||||||
|
|
||||||
int deriveConfirmationCode(byte[] secret, boolean initiator);
|
int deriveConfirmationCode(byte[] secret);
|
||||||
|
|
||||||
byte[] deriveNextSecret(byte[] secret, int index, long connection);
|
byte[] deriveNextSecret(byte[] secret, int index, long connection);
|
||||||
|
|
||||||
|
|||||||
@@ -104,14 +104,14 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
if(secret.length != SECRET_KEY_BYTES)
|
if(secret.length != SECRET_KEY_BYTES)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
// The label and context must leave a byte free for the counter
|
// The label and context must leave a byte free for the counter
|
||||||
if(label.length + context.length + 4 > KEY_DERIVATION_IV_BYTES)
|
if(label.length + context.length + 2 >= KEY_DERIVATION_IV_BYTES)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
// The IV contains the length-prefixed label and context
|
// The IV contains the length-prefixed label and context
|
||||||
byte[] ivBytes = new byte[KEY_DERIVATION_IV_BYTES];
|
byte[] ivBytes = new byte[KEY_DERIVATION_IV_BYTES];
|
||||||
ByteUtils.writeUint8(label.length, ivBytes, 0);
|
ByteUtils.writeUint8(label.length, ivBytes, 0);
|
||||||
System.arraycopy(label, 0, ivBytes, 2, label.length);
|
System.arraycopy(label, 0, ivBytes, 1, label.length);
|
||||||
ByteUtils.writeUint8(context.length, ivBytes, label.length + 2);
|
ByteUtils.writeUint8(context.length, ivBytes, label.length + 1);
|
||||||
System.arraycopy(context, 0, ivBytes, label.length + 4, context.length);
|
System.arraycopy(context, 0, ivBytes, label.length + 2, context.length);
|
||||||
// Use the secret and the IV to encrypt a blank plaintext
|
// Use the secret and the IV to encrypt a blank plaintext
|
||||||
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||||
ErasableKey key = new ErasableKeyImpl(secret, SECRET_KEY_ALGO);
|
ErasableKey key = new ErasableKeyImpl(secret, SECRET_KEY_ALGO);
|
||||||
@@ -178,7 +178,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
if(messageDigest.getDigestLength() < SECRET_KEY_BYTES)
|
if(messageDigest.getDigestLength() < SECRET_KEY_BYTES)
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
// All fields are length-prefixed
|
// All fields are length-prefixed
|
||||||
byte[] length = new byte[4];
|
byte[] length = new byte[1];
|
||||||
ByteUtils.writeUint8(rawSecret.length, length, 0);
|
ByteUtils.writeUint8(rawSecret.length, length, 0);
|
||||||
messageDigest.update(length);
|
messageDigest.update(length);
|
||||||
messageDigest.update(rawSecret);
|
messageDigest.update(rawSecret);
|
||||||
@@ -213,19 +213,13 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
return counterModeKdf(secret, NEXT, context);
|
return counterModeKdf(secret, NEXT, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int deriveConfirmationCode(byte[] secret, boolean initiator) {
|
public int deriveConfirmationCode(byte[] secret) {
|
||||||
byte[] context = initiator ? INITIATOR : RESPONDER;
|
byte[] output = counterModeKdf(secret, CODE, CODE);
|
||||||
byte[] output = counterModeKdf(secret, CODE, context);
|
int code = ByteUtils.readUint(output, CODE_BITS);
|
||||||
int code = extractCode(output);
|
|
||||||
ByteUtils.erase(output);
|
ByteUtils.erase(output);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int extractCode(byte[] secret) {
|
|
||||||
// Convert the first CODE_BITS bits of the secret into an unsigned int
|
|
||||||
return ByteUtils.readUint(secret, CODE_BITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyPair generateKeyPair() {
|
public KeyPair generateKeyPair() {
|
||||||
return keyPairGenerator.generateKeyPair();
|
return keyPairGenerator.generateKeyPair();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ class InvitationStarterImpl implements InvitationStarter {
|
|||||||
callback.showFailure(INVALID_KEY);
|
callback.showFailure(INVALID_KEY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int initCode = crypto.deriveConfirmationCode(secrets[0], true);
|
int initCode = crypto.deriveConfirmationCode(secrets[0]);
|
||||||
int respCode = crypto.deriveConfirmationCode(secrets[1], false);
|
int respCode = crypto.deriveConfirmationCode(secrets[1]);
|
||||||
int ourCode = initiator ? initCode : respCode;
|
int ourCode = initiator ? initCode : respCode;
|
||||||
int theirCode = initiator ? respCode : initCode;
|
int theirCode = initiator ? respCode : initCode;
|
||||||
// Compare the confirmation codes
|
// Compare the confirmation codes
|
||||||
|
|||||||
Reference in New Issue
Block a user