diff --git a/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java b/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java index 8ffd06213e6e2a90cfa38b58a00bcf34297d42f4..11631f22fda6db0351682106a9f0828d2c02e20f 100644 --- a/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java +++ b/briar-api/src/org/briarproject/api/crypto/CryptoComponent.java @@ -36,11 +36,10 @@ public interface CryptoComponent { int deriveBTConfirmationCode(SecretKey master, boolean alice); /** - * Derives a header key for an invitation stream from the given master - * secret. + * Derives a stream header key from the given master secret. * @param alice whether the key is for use by Alice or Bob. */ - SecretKey deriveBTInvitationKey(SecretKey master, boolean alice); + SecretKey deriveHeaderKey(SecretKey master, boolean alice); /** * Derives a nonce from the given master secret for one of the parties to @@ -107,7 +106,7 @@ public interface CryptoComponent { * Derives a master secret from two public keys and one of the corresponding * private keys. * <p/> - * Part of BQP. This is a helper method that calls + * This is a helper method that calls * deriveMasterSecret(deriveSharedSecret(theirPublicKey, ourKeyPair, alice)) * * @param theirPublicKey the ephemeral public key of the remote party diff --git a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java index 7219460e6baec45801f9ff3a788c6e297c5d4761..943d02de98598359dedbf1767411a6334b8ed504 100644 --- a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java +++ b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java @@ -93,6 +93,9 @@ public class ContactExchangeTaskImpl extends Thread @Override public void run() { + // Derive the header keys for the transport streams + SecretKey aliceHeaderKey = crypto.deriveHeaderKey(masterSecret, true); + SecretKey bobHeaderKey = crypto.deriveHeaderKey(masterSecret, false); BdfReader r; BdfWriter w; try { @@ -100,13 +103,13 @@ public class ContactExchangeTaskImpl extends Thread InputStream streamReader = streamReaderFactory.createInvitationStreamReader( conn.getReader().getInputStream(), - masterSecret); + alice ? bobHeaderKey : aliceHeaderKey); r = bdfReaderFactory.createReader(streamReader); // Create the writers OutputStream streamWriter = streamWriterFactory.createInvitationStreamWriter( conn.getWriter().getOutputStream(), - masterSecret); + alice ? aliceHeaderKey : bobHeaderKey); w = bdfWriterFactory.createWriter(streamWriter); } catch (IOException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -115,7 +118,7 @@ public class ContactExchangeTaskImpl extends Thread return; } - // Derive the invitation nonces + // Derive the nonces to be signed byte[] aliceNonce = crypto.deriveSignatureNonce(masterSecret, true); byte[] bobNonce = crypto.deriveSignatureNonce(masterSecret, false); @@ -155,8 +158,8 @@ public class ContactExchangeTaskImpl extends Thread try { // Add the contact - ContactId contactId = - addContact(remoteAuthor, masterSecret, timestamp, true); + ContactId contactId = addContact(remoteAuthor, masterSecret, + timestamp, alice); // Reuse the connection as a transport connection connectionManager.manageOutgoingConnection(contactId, transportId, conn); diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java index c17f67901044af736af07dfc5f21e05c9536a809..825c3720f5188500ec89aa7a83fb70096b14270a 100644 --- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java +++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java @@ -63,24 +63,22 @@ class CryptoComponentImpl implements CryptoComponent { return s.getBytes(Charset.forName("US-ASCII")); } - // KDF label for bluetooth master key derivation - private static final byte[] BT_MASTER = ascii("MASTER"); // KDF labels for bluetooth confirmation code derivation private static final byte[] BT_A_CONFIRM = ascii("ALICE_CONFIRMATION_CODE"); private static final byte[] BT_B_CONFIRM = ascii("BOB_CONFIRMATION_CODE"); - // KDF labels for bluetooth invitation stream header key derivation - private static final byte[] BT_A_INVITE = ascii("ALICE_INVITATION_KEY"); - private static final byte[] BT_B_INVITE = ascii("BOB_INVITATION_KEY"); - // KDF labels for bluetooth signature nonce derivation - private static final byte[] BT_A_NONCE = ascii("ALICE_SIGNATURE_NONCE"); - private static final byte[] BT_B_NONCE = ascii("BOB_SIGNATURE_NONCE"); + // KDF labels for contact exchange stream header key derivation + private static final byte[] A_INVITE = ascii("ALICE_INVITATION_KEY"); + private static final byte[] B_INVITE = ascii("BOB_INVITATION_KEY"); + // KDF labels for contact exchange signature nonce derivation + private static final byte[] A_SIG_NONCE = ascii("ALICE_SIGNATURE_NONCE"); + private static final byte[] B_SIG_NONCE = ascii("BOB_SIGNATURE_NONCE"); // Hash label for BQP public key commitment derivation private static final byte[] COMMIT = ascii("COMMIT"); - // Hash label for BQP shared secret derivation + // Hash label for shared secret derivation private static final byte[] SHARED_SECRET = ascii("SHARED_SECRET"); // KDF label for BQP confirmation key derivation private static final byte[] CONFIRMATION_KEY = ascii("CONFIRMATION_KEY"); - // KDF label for BQP master key derivation + // KDF label for master key derivation private static final byte[] MASTER_KEY = ascii("MASTER_KEY"); // KDF labels for tag key derivation private static final byte[] A_TAG = ascii("ALICE_TAG_KEY"); @@ -210,12 +208,14 @@ class CryptoComponentImpl implements CryptoComponent { return ByteUtils.readUint(b, CODE_BITS); } - public SecretKey deriveBTInvitationKey(SecretKey master, boolean alice) { - return new SecretKey(macKdf(master, alice ? BT_A_INVITE : BT_B_INVITE)); + public SecretKey deriveHeaderKey(SecretKey master, + boolean alice) { + return new SecretKey(macKdf(master, alice ? A_INVITE : B_INVITE)); } - public byte[] deriveSignatureNonce(SecretKey master, boolean alice) { - return macKdf(master, alice ? BT_A_NONCE : BT_B_NONCE); + public byte[] deriveSignatureNonce(SecretKey master, + boolean alice) { + return macKdf(master, alice ? A_SIG_NONCE : B_SIG_NONCE); } public byte[] deriveKeyCommitment(byte[] publicKey) { @@ -438,29 +438,6 @@ class CryptoComponentImpl implements CryptoComponent { } } - // Key derivation function based on a hash function - see NIST SP 800-56A, - // section 5.8 - private byte[] hashKdf(byte[]... inputs) { - Digest digest = new Blake2sDigest(); - // The output of the hash function must be long enough to use as a key - int hashLength = digest.getDigestSize(); - if (hashLength < SecretKey.LENGTH) throw new IllegalStateException(); - // Calculate the hash over the concatenated length-prefixed inputs - byte[] length = new byte[INT_32_BYTES]; - for (byte[] input : inputs) { - ByteUtils.writeUint32(input.length, length, 0); - digest.update(length, 0, length.length); - digest.update(input, 0, input.length); - } - byte[] hash = new byte[hashLength]; - digest.doFinal(hash, 0); - // The output is the first SecretKey.LENGTH bytes of the hash - if (hash.length == SecretKey.LENGTH) return hash; - byte[] truncated = new byte[SecretKey.LENGTH]; - System.arraycopy(hash, 0, truncated, 0, truncated.length); - return truncated; - } - // Key derivation function based on a pseudo-random function - see // NIST SP 800-108, section 5.1 private byte[] macKdf(SecretKey key, byte[]... inputs) { diff --git a/briar-core/src/org/briarproject/invitation/AliceConnector.java b/briar-core/src/org/briarproject/invitation/AliceConnector.java index fc02774043417d8dc57bf443f4e54cb4941c8d93..b2947ece4db90335101bc6cb4d1a82424cbaa8a6 100644 --- a/briar-core/src/org/briarproject/invitation/AliceConnector.java +++ b/briar-core/src/org/briarproject/invitation/AliceConnector.java @@ -125,8 +125,8 @@ class AliceConnector extends Connector { if (LOG.isLoggable(INFO)) LOG.info(pluginName + " confirmation succeeded"); // Derive the header keys - SecretKey aliceHeaderKey = crypto.deriveBTInvitationKey(master, true); - SecretKey bobHeaderKey = crypto.deriveBTInvitationKey(master, false); + SecretKey aliceHeaderKey = crypto.deriveHeaderKey(master, true); + SecretKey bobHeaderKey = crypto.deriveHeaderKey(master, false); // Create the readers InputStream streamReader = streamReaderFactory.createInvitationStreamReader(in, diff --git a/briar-core/src/org/briarproject/invitation/BobConnector.java b/briar-core/src/org/briarproject/invitation/BobConnector.java index 2f1cfc2e8dcf2a1e4b826fa66d0ca5837e155f43..1460b953ec1b3ec222ca14fc5e27ebfc93447966 100644 --- a/briar-core/src/org/briarproject/invitation/BobConnector.java +++ b/briar-core/src/org/briarproject/invitation/BobConnector.java @@ -125,8 +125,10 @@ class BobConnector extends Connector { if (LOG.isLoggable(INFO)) LOG.info(pluginName + " confirmation succeeded"); // Derive the header keys - SecretKey aliceHeaderKey = crypto.deriveBTInvitationKey(master, true); - SecretKey bobHeaderKey = crypto.deriveBTInvitationKey(master, false); + SecretKey aliceHeaderKey = crypto.deriveHeaderKey(master, + true); + SecretKey bobHeaderKey = crypto.deriveHeaderKey(master, + false); // Create the readers InputStream streamReader = streamReaderFactory.createInvitationStreamReader(in, @@ -138,8 +140,10 @@ class BobConnector extends Connector { bobHeaderKey); w = bdfWriterFactory.createWriter(streamWriter); // Derive the nonces - byte[] aliceNonce = crypto.deriveSignatureNonce(master, true); - byte[] bobNonce = crypto.deriveSignatureNonce(master, false); + byte[] aliceNonce = crypto.deriveSignatureNonce(master, + true); + byte[] bobNonce = crypto.deriveSignatureNonce(master, + false); // Exchange pseudonyms, signed nonces and timestamps Author remoteAuthor; long remoteTimestamp;