mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Key derivation fixes, renamed a key derivation method.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user