Rename crypto methods and constants for Bluetooth key agreement

This commit is contained in:
str4d
2016-01-27 20:21:05 +00:00
parent 35090f4d0e
commit 4d7a23779a
8 changed files with 70 additions and 70 deletions

View File

@@ -62,17 +62,17 @@ class CryptoComponentImpl implements CryptoComponent {
return s.getBytes(Charset.forName("US-ASCII"));
}
// KDF label for master key derivation
private static final byte[] MASTER = ascii("MASTER");
// KDF labels for confirmation code derivation
private static final byte[] A_CONFIRM = ascii("ALICE_CONFIRMATION_CODE");
private static final byte[] B_CONFIRM = ascii("BOB_CONFIRMATION_CODE");
// KDF labels for invitation 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 signature nonce derivation
private static final byte[] A_NONCE = ascii("ALICE_SIGNATURE_NONCE");
private static final byte[] B_NONCE = ascii("BOB_SIGNATURE_NONCE");
// 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 tag key derivation
private static final byte[] A_TAG = ascii("ALICE_TAG_KEY");
private static final byte[] B_TAG = ascii("BOB_TAG_KEY");
@@ -128,6 +128,25 @@ class CryptoComponentImpl implements CryptoComponent {
return secureRandom;
}
// Package access for testing
byte[] performRawKeyAgreement(PrivateKey priv, PublicKey pub)
throws GeneralSecurityException {
if (!(priv instanceof Sec1PrivateKey))
throw new IllegalArgumentException();
if (!(pub instanceof Sec1PublicKey))
throw new IllegalArgumentException();
ECPrivateKeyParameters ecPriv = ((Sec1PrivateKey) priv).getKey();
ECPublicKeyParameters ecPub = ((Sec1PublicKey) pub).getKey();
long now = System.currentTimeMillis();
ECDHCBasicAgreement agreement = new ECDHCBasicAgreement();
agreement.init(ecPriv);
byte[] secret = agreement.calculateAgreement(ecPub).toByteArray();
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Deriving shared secret took " + duration + " ms");
return secret;
}
public Signature getSignature() {
return new SignatureImpl(secureRandom);
}
@@ -170,14 +189,14 @@ class CryptoComponentImpl implements CryptoComponent {
return signatureKeyParser;
}
public int generateInvitationCode() {
public int generateBTInvitationCode() {
int codeBytes = (CODE_BITS + 7) / 8;
byte[] random = new byte[codeBytes];
secureRandom.nextBytes(random);
return ByteUtils.readUint(random, CODE_BITS);
}
public SecretKey deriveMasterSecret(byte[] theirPublicKey,
public SecretKey deriveBTMasterSecret(byte[] theirPublicKey,
KeyPair ourKeyPair, boolean alice) throws GeneralSecurityException {
MessageDigest messageDigest = getMessageDigest();
byte[] ourPublicKey = ourKeyPair.getPublic().getEncoded();
@@ -194,41 +213,22 @@ class CryptoComponentImpl implements CryptoComponent {
PrivateKey ourPriv = ourKeyPair.getPrivate();
PublicKey theirPub = agreementKeyParser.parsePublicKey(theirPublicKey);
// The raw secret comes from the key agreement algorithm
byte[] raw = deriveSharedSecret(ourPriv, theirPub);
byte[] raw = performRawKeyAgreement(ourPriv, theirPub);
// Derive the master secret from the raw secret using the hash KDF
return new SecretKey(hashKdf(raw, MASTER, aliceInfo, bobInfo));
return new SecretKey(hashKdf(raw, BT_MASTER, aliceInfo, bobInfo));
}
// Package access for testing
byte[] deriveSharedSecret(PrivateKey priv, PublicKey pub)
throws GeneralSecurityException {
if (!(priv instanceof Sec1PrivateKey))
throw new IllegalArgumentException();
if (!(pub instanceof Sec1PublicKey))
throw new IllegalArgumentException();
ECPrivateKeyParameters ecPriv = ((Sec1PrivateKey) priv).getKey();
ECPublicKeyParameters ecPub = ((Sec1PublicKey) pub).getKey();
long now = System.currentTimeMillis();
ECDHCBasicAgreement agreement = new ECDHCBasicAgreement();
agreement.init(ecPriv);
byte[] secret = agreement.calculateAgreement(ecPub).toByteArray();
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Deriving shared secret took " + duration + " ms");
return secret;
}
public int deriveConfirmationCode(SecretKey master, boolean alice) {
byte[] b = macKdf(master, alice ? A_CONFIRM : B_CONFIRM);
public int deriveBTConfirmationCode(SecretKey master, boolean alice) {
byte[] b = macKdf(master, alice ? BT_A_CONFIRM : BT_B_CONFIRM);
return ByteUtils.readUint(b, CODE_BITS);
}
public SecretKey deriveInvitationKey(SecretKey master, boolean alice) {
return new SecretKey(macKdf(master, alice ? A_INVITE : B_INVITE));
public SecretKey deriveBTInvitationKey(SecretKey master, boolean alice) {
return new SecretKey(macKdf(master, alice ? BT_A_INVITE : BT_B_INVITE));
}
public byte[] deriveSignatureNonce(SecretKey master, boolean alice) {
return macKdf(master, alice ? A_NONCE : B_NONCE);
public byte[] deriveBTSignatureNonce(SecretKey master, boolean alice) {
return macKdf(master, alice ? BT_A_NONCE : BT_B_NONCE);
}
public TransportKeys deriveTransportKeys(TransportId t,

View File

@@ -93,8 +93,8 @@ class AliceConnector extends Connector {
}
// The key agreement succeeded - derive the confirmation codes
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
int aliceCode = crypto.deriveConfirmationCode(master, true);
int bobCode = crypto.deriveConfirmationCode(master, false);
int aliceCode = crypto.deriveBTConfirmationCode(master, true);
int bobCode = crypto.deriveBTConfirmationCode(master, false);
group.keyAgreementSucceeded(aliceCode, bobCode);
// Exchange confirmation results
boolean localMatched, remoteMatched;
@@ -128,8 +128,8 @@ class AliceConnector extends Connector {
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " confirmation succeeded");
// Derive the header keys
SecretKey aliceHeaderKey = crypto.deriveInvitationKey(master, true);
SecretKey bobHeaderKey = crypto.deriveInvitationKey(master, false);
SecretKey aliceHeaderKey = crypto.deriveBTInvitationKey(master, true);
SecretKey bobHeaderKey = crypto.deriveBTInvitationKey(master, false);
// Create the readers
InputStream streamReader =
streamReaderFactory.createInvitationStreamReader(in,
@@ -141,8 +141,8 @@ class AliceConnector extends Connector {
aliceHeaderKey);
w = bdfWriterFactory.createWriter(streamWriter);
// Derive the invitation nonces
byte[] aliceNonce = crypto.deriveSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveSignatureNonce(master, false);
byte[] aliceNonce = crypto.deriveBTSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveBTSignatureNonce(master, false);
// Exchange pseudonyms, signed nonces, and timestamps
Author remoteAuthor;
long remoteTimestamp;

View File

@@ -93,8 +93,8 @@ class BobConnector extends Connector {
}
// The key agreement succeeded - derive the confirmation codes
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
int aliceCode = crypto.deriveConfirmationCode(master, true);
int bobCode = crypto.deriveConfirmationCode(master, false);
int aliceCode = crypto.deriveBTConfirmationCode(master, true);
int bobCode = crypto.deriveBTConfirmationCode(master, false);
group.keyAgreementSucceeded(bobCode, aliceCode);
// Exchange confirmation results
boolean localMatched, remoteMatched;
@@ -128,8 +128,8 @@ class BobConnector extends Connector {
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " confirmation succeeded");
// Derive the header keys
SecretKey aliceHeaderKey = crypto.deriveInvitationKey(master, true);
SecretKey bobHeaderKey = crypto.deriveInvitationKey(master, false);
SecretKey aliceHeaderKey = crypto.deriveBTInvitationKey(master, true);
SecretKey bobHeaderKey = crypto.deriveBTInvitationKey(master, false);
// Create the readers
InputStream streamReader =
streamReaderFactory.createInvitationStreamReader(in,
@@ -141,8 +141,8 @@ 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.deriveBTSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveBTSignatureNonce(master, false);
// Exchange pseudonyms, signed nonces and timestamps
Author remoteAuthor;
long remoteTimestamp;

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.deriveMasterSecret(key, keyPair, alice);
return crypto.deriveBTMasterSecret(key, keyPair, alice);
}
protected void sendConfirmation(BdfWriter w, boolean confirmed)