From ddfbd2e7bdff41c9d01c7eee63b7f3b20fc94c36 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sat, 27 Feb 2021 18:33:04 +0100 Subject: [PATCH] dash ble tlk: start generating keys --- .../dash/driver/comm/ltk/LTKExchanger.kt | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ltk/LTKExchanger.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ltk/LTKExchanger.kt index 7b7fa8dcb1..455f0f1575 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ltk/LTKExchanger.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ltk/LTKExchanger.kt @@ -1,21 +1,32 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk +import com.google.crypto.tink.mac.AesCmacKeyManager +import com.google.crypto.tink.proto.AesCmac import com.google.crypto.tink.subtle.X25519 + import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManagerImpl +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.MessageIOException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding import info.nightscout.androidaps.utils.extensions.hexStringToByteArray import info.nightscout.androidaps.utils.extensions.toHex +import org.spongycastle.crypto.engines.AESEngine import java.security.SecureRandom internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgIO: MessageIO) { - private val privateKey = X25519.generatePrivateKey() - private val nonce = ByteArray(16) + private val pdmPrivate = X25519.generatePrivateKey() + private val pdmPublic = X25519.publicFromPrivate(pdmPrivate) + private var podPublic = ByteArray(PUBLIC_KEY_SIZE) + private var podNonce = ByteArray(NONCE_SIZE) + private val pdmNonce = ByteArray(NONCE_SIZE) + private val confPdm = ByteArray(CONF_SIZE) + private val confPod = ByteArray(CONF_SIZE) + private val controllerId = Id.fromInt(OmnipodDashBleManagerImpl.CONTROLLER_ID) val nodeId = controllerId.increment() private var seq: Byte = 1 @@ -24,7 +35,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI init { val random = SecureRandom() - random.nextBytes(nonce) + random.nextBytes(pdmNonce) } fun negotiateLTKAndNonce(): LTK? { @@ -41,9 +52,9 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI val podSps1 = msgIO.receiveMessage() aapsLogger.info(LTag.PUMPBTCOMM, "Received message: %s", podSps1) processSps1FromPod(podSps1) - + // now we have all the data to generate: confPod, confPdm, ltk and noncePrefix + generateKeys() seq++ - // send SPS2 val sps2 = sps2() msgIO.sendMesssage(sps2.messagePacket) @@ -52,6 +63,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI val podSps2 = msgIO.receiveMessage() validatePodSps2(podSps2) + seq++ // send SP0GP0 msgIO.sendMesssage(sp0gp0().messagePacket) // read P0 @@ -83,7 +95,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI } private fun sps1(): PairMessage { - val publicKey = X25519.publicFromPrivate(privateKey) + val publicKey = X25519.publicFromPrivate(pdmPrivate) val payload = StringLengthPrefixEncoding.formatKeys( arrayOf("SPS1="), arrayOf(publicKey + nonce), @@ -98,7 +110,11 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI private fun processSps1FromPod(msg: MessagePacket) { aapsLogger.debug(LTag.PUMPBTCOMM, "Received SPS1 from pod: ${msg.payload.toHex()}") - + if (msg.payload.size != 48) { + throw MessageIOException() + } + podPublic = msg.payload.copyOfRange(0, PUBLIC_KEY_SIZE) + podNonce = msg.payload.copyOfRange(PUBLIC_KEY_SIZE, PUBLIC_KEY_SIZE+ NONCE_SIZE) } private fun sps2(): PairMessage { @@ -124,8 +140,23 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI TODO("implement") } - companion object { + fun generateKeys() { + val curveLTK = X25519.computeSharedSecret(pdmPrivate, podPublic) + aapsLogger.debug(LTag.PUMPBTCOMM, "LTK, donna key: ${curveLTK.toHex()}") + //first_key = data.pod_public[-4:] + data.pdm_public[-4:] + data.pod_nonce[-4:] + data.pdm_nonce[-4:] + + val firstKey = podPublic.copyOfRange(podPublic.size-4, podPublic.size) + + pdmPublic.copyOfRange(pdmPublic.size-4, pdmPublic.size) + + podNonce.copyOfRange(podNonce.size-4, podNonce.size) + + pdmNonce.copyOfRange(pdmNonce.size-4, pdmNonce.size) + aapsLogger.debug(LTag.PUMPBTCOMM, "LTK, first key: ${firstKey.toHex()}") + } + + companion object { + private val PUBLIC_KEY_SIZE = 32 + private val NONCE_SIZE = 16 + private val CONF_SIZE = 16 private val GET_POD_STATUS_HEX_COMMAND = "ffc32dbd08030e0100008a" // TODO for now we are assuming this command is build out of constant parameters, use a proper command builder for that. } } \ No newline at end of file