Migrate Bluetooth protocol to BQP's master secret derivation

This commit is contained in:
str4d
2016-02-02 02:31:30 +00:00
parent 77e4ec381a
commit c822623677
4 changed files with 25 additions and 33 deletions

View File

@@ -29,14 +29,6 @@ public interface CryptoComponent {
/** Generates a random invitation code. */
int generateBTInvitationCode();
/**
* Derives a shared master secret from two public keys and one of the
* corresponding private keys.
* @param alice whether the private key belongs to Alice or Bob.
*/
SecretKey deriveBTMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
boolean alice) throws GeneralSecurityException;
/**
* Derives a confirmation code from the given master secret.
* @param alice whether the code is for use by Alice or Bob.
@@ -111,6 +103,22 @@ public interface CryptoComponent {
*/
SecretKey deriveMasterSecret(SecretKey sharedSecret);
/**
* 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
* deriveMasterSecret(deriveSharedSecret(theirPublicKey, ourKeyPair, alice))
*
* @param theirPublicKey the ephemeral public key of the remote party
* @param ourKeyPair our ephemeral keypair
* @param alice true if ourKeyPair belongs to Alice
* @return the shared secret
* @throws GeneralSecurityException
*/
SecretKey deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
boolean alice) throws GeneralSecurityException;
/**
* Derives initial transport keys for the given transport in the given
* rotation period from the given master secret.

View File

@@ -205,28 +205,6 @@ class CryptoComponentImpl implements CryptoComponent {
return ByteUtils.readUint(random, CODE_BITS);
}
public SecretKey deriveBTMasterSecret(byte[] theirPublicKey,
KeyPair ourKeyPair, boolean alice) throws GeneralSecurityException {
MessageDigest messageDigest = getMessageDigest();
byte[] ourPublicKey = ourKeyPair.getPublic().getEncoded();
byte[] ourHash = messageDigest.digest(ourPublicKey);
byte[] theirHash = messageDigest.digest(theirPublicKey);
byte[] aliceInfo, bobInfo;
if (alice) {
aliceInfo = ourHash;
bobInfo = theirHash;
} else {
aliceInfo = theirHash;
bobInfo = ourHash;
}
PrivateKey ourPriv = ourKeyPair.getPrivate();
PublicKey theirPub = agreementKeyParser.parsePublicKey(theirPublicKey);
// The raw secret comes from the key agreement algorithm
byte[] raw = performRawKeyAgreement(ourPriv, theirPub);
// Derive the master secret from the raw secret using the hash KDF
return new SecretKey(hashKdf(raw, BT_MASTER, aliceInfo, bobInfo));
}
public int deriveBTConfirmationCode(SecretKey master, boolean alice) {
byte[] b = macKdf(master, alice ? BT_A_CONFIRM : BT_B_CONFIRM);
return ByteUtils.readUint(b, CODE_BITS);
@@ -290,6 +268,12 @@ class CryptoComponentImpl implements CryptoComponent {
return new SecretKey(macKdf(sharedSecret, MASTER_KEY));
}
public SecretKey deriveMasterSecret(byte[] theirPublicKey,
KeyPair ourKeyPair, boolean alice) throws GeneralSecurityException {
return deriveMasterSecret(deriveSharedSecret(
theirPublicKey,ourKeyPair, alice));
}
public TransportKeys deriveTransportKeys(TransportId t,
SecretKey master, long rotationPeriod, boolean alice) {
// Keys for the previous period are derived from the master secret

View File

@@ -146,7 +146,7 @@ abstract class Connector extends Thread {
// Derive the master secret
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " deriving master secret");
return crypto.deriveBTMasterSecret(key, keyPair, alice);
return crypto.deriveMasterSecret(key, keyPair, alice);
}
protected void sendConfirmation(BdfWriter w, boolean confirmed)

View File

@@ -20,8 +20,8 @@ public class KeyAgreementTest extends BriarTestCase {
byte[] aPub = aPair.getPublic().getEncoded();
KeyPair bPair = crypto.generateAgreementKeyPair();
byte[] bPub = bPair.getPublic().getEncoded();
SecretKey aMaster = crypto.deriveBTMasterSecret(aPub, bPair, true);
SecretKey bMaster = crypto.deriveBTMasterSecret(bPub, aPair, false);
SecretKey aMaster = crypto.deriveMasterSecret(aPub, bPair, true);
SecretKey bMaster = crypto.deriveMasterSecret(bPub, aPair, false);
assertArrayEquals(aMaster.getBytes(), bMaster.getBytes());
}