From 9c586c494287a34647c2e3d81662e48da4980d27 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 4 Mar 2021 18:59:03 +0100 Subject: [PATCH] dash encryption: add encryption and decryption for messsages --- .../dash/driver/comm/endecrypt/EnDecrypt.kt | 63 +++++++++++++++++++ .../driver/comm/endecrypt/EnDecryptTest.kt | 59 +++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt create mode 100644 omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt new file mode 100644 index 0000000000..a08b79bf8a --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt @@ -0,0 +1,63 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt + +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket +import info.nightscout.androidaps.utils.extensions.toHex +import org.spongycastle.crypto.engines.AESEngine +import org.spongycastle.crypto.modes.CCMBlockCipher +import org.spongycastle.crypto.params.AEADParameters +import org.spongycastle.crypto.params.KeyParameter + +class EnDecrypt(private val aapsLogger: AAPSLogger, private val nonce: Nonce, private val ck: ByteArray) { + + val engine = AESEngine() + val cipher = CCMBlockCipher(engine) + + fun decrypt(msg: MessagePacket): MessagePacket { + val payload = msg.payload + val header = msg.asByteArray().copyOfRange(0, 16) + + val n = nonce.increment() + aapsLogger.debug(LTag.PUMPBTCOMM, "Decrypt header ${header.toHex()} payload: ${payload.toHex()}") + aapsLogger.debug(LTag.PUMPBTCOMM, "Decrypt NONCE ${n.toHex()}") + cipher.init( + false, AEADParameters( + KeyParameter(ck), + MAC_SIZE * 8, // in bits + n, + header + ) + ) + val decryptedPayload = ByteArray(payload.size - MAC_SIZE) + cipher.processPacket(payload, 0, payload.size, decryptedPayload, 0) + return msg.copy(payload = decryptedPayload) + } + + fun encrypt(headerMessage: MessagePacket): MessagePacket { + val payload = headerMessage.payload + val header = headerMessage.asByteArray(true).copyOfRange(0, 16) + + val n = nonce.increment() + aapsLogger.debug(LTag.PUMPBTCOMM, "Encrypt header ${header.toHex()} payload: ${payload.toHex()}") + aapsLogger.debug(LTag.PUMPBTCOMM, "Encrypt NONCE ${n.toHex()}") + val encryptedPayload = ByteArray(payload.size + MAC_SIZE) + + cipher.init( + true, AEADParameters( + KeyParameter(ck), + MAC_SIZE * 8, // in bits + n, + header + ) + ) + cipher.processPacket(payload, 0, payload.size, encryptedPayload, 0) + + return headerMessage.copy(payload = encryptedPayload) + } + + companion object { + + private val MAC_SIZE = 8 + } +} \ No newline at end of file diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt new file mode 100644 index 0000000000..05851bd261 --- /dev/null +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt @@ -0,0 +1,59 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt + +import info.nightscout.androidaps.logging.AAPSLoggerTest +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket +import info.nightscout.androidaps.utils.extensions.toHex +import org.junit.Assert +import org.junit.Test +import org.spongycastle.util.encoders.Hex + +class EnDecryptTest { + + @Test + fun decrypt() { + val aapsLogger = AAPSLoggerTest() + val enDecrypt = EnDecrypt( + aapsLogger, + Nonce( + Hex.decode("dda23c090a0a0a0a"), + Hex.decode("0000000001") + ), + Hex.decode("ba1283744b6de9fab6d9b77d95a71d6e"), + ) + val encryptedMessage = Hex.decode( + "54571101070003400242000002420001" + + "e09158bcb0285a81bf30635f3a17ee73f0afbb3286bc524a8a66" + + "fb1bc5b001e56543" + ) + val decrypted = Hex.decode("53302e303d000effffffff00060704ffffffff82b22c47302e30") + val msg = MessagePacket.parse(encryptedMessage) + val decryptedMsg = enDecrypt.decrypt(msg) + + Assert.assertEquals(decrypted.toHex(), decryptedMsg.payload.toHex()) + } + + @Test + fun encrypt() { + val aapsLogger = AAPSLoggerTest() + val enDecrypt = EnDecrypt( + aapsLogger, + Nonce( + Hex.decode("dda23c090a0a0a0a"), + Hex.decode("0000000001") + ), + Hex.decode("ba1283744b6de9fab6d9b77d95a71d6e"), + ) + val encryptedMessage = Hex.decode( + "54571101070003400242000002420001" + + "e09158bcb0285a81bf30635f3a17ee73f0afbb3286bc524a8a66" + + "fb1bc5b001e56543" + ) + val command = Hex.decode("53302e303d000effffffff00060704ffffffff82b22c47302e30") + val msg = MessagePacket.parse(encryptedMessage).copy(payload = command) // copy for the headers + + val encrypted = enDecrypt.encrypt(msg) + + Assert.assertEquals(encryptedMessage.toHex(), encrypted.asByteArray().toHex()) + + } +} \ No newline at end of file