diff --git a/multiplatform-crypto/build.gradle.kts b/multiplatform-crypto/build.gradle.kts index ea57cb1..e9a1922 100644 --- a/multiplatform-crypto/build.gradle.kts +++ b/multiplatform-crypto/build.gradle.kts @@ -149,8 +149,6 @@ kotlin { } val nativeMain by creating { dependsOn(commonMain) - dependencies { - } } val nativeTest by creating { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt index b775a68..69e2a00 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt @@ -64,12 +64,6 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array> = (0 until 4).map { outerCounter -> Array(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } }.toTypedArray() diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt index a9a3038..4d7125e 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbc.kt @@ -97,7 +97,11 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa var currentOutput: Array = arrayOf() var previousEncrypted: Array = arrayOf() - val iv = initializationVector ?: SRNG.getRandomBytes(16) + val initVector = if (initializationVector.isNullOrEmpty()) { + SRNG.getRandomBytes(16) + } else { + initializationVector + } val output = MutableList>(0) { arrayOf() } @@ -158,7 +162,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa } return EncryptedDataAndInitializationVector( output.reversed().foldRight(Array(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, - iv + initVector ) } @@ -193,7 +197,8 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa return when (mode) { Mode.ENCRYPT -> { currentOutput = if (currentOutput.isEmpty()) { - Aes.encrypt(aesKey, data xor iv) + println("IV: $initVector") + Aes.encrypt(aesKey, data xor initVector) } else { Aes.encrypt(aesKey, data xor currentOutput) } @@ -201,7 +206,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa } Mode.DECRYPT -> { if (currentOutput.isEmpty()) { - currentOutput = Aes.decrypt(aesKey, data) xor iv + currentOutput = Aes.decrypt(aesKey, data) xor initVector } else { currentOutput = Aes.decrypt(aesKey, data) xor previousEncrypted } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt index a966dde..4d5373a 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtr.kt @@ -78,7 +78,11 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou var currentOutput: Array = arrayOf() var previousEncrypted: Array = arrayOf() - val counterStart = initialCounter ?: SRNG.getRandomBytes(16) + val counterStart = if (initialCounter.isNullOrEmpty()) { + SRNG.getRandomBytes(16) + } else { + initialCounter + } var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Endianness.BIG)) val output = MutableList>(0) { arrayOf() } @@ -158,17 +162,29 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou } private fun consumeBlock(data: Array, blockCount: ModularBigInteger): Array { + val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes() return when (mode) { Mode.ENCRYPT -> { - Aes.encrypt(aesKey, blockCount.toUByteArray(Endianness.BIG)) xor data + Aes.encrypt(aesKey, blockCountAsByteArray) xor data } Mode.DECRYPT -> { - Aes.encrypt(aesKey, blockCount.toUByteArray(Endianness.BIG)) xor data + Aes.encrypt(aesKey, blockCountAsByteArray) xor data } } } + private fun Array.expandCounterTo16Bytes() : Array { + return if (this.size < 16) { + println("Expanding") + val diff = 16 - this.size + val pad = Array(diff) { 0U } + pad + this + } else { + this + } + } + } @ExperimentalUnsignedTypes diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt index 98b56a7..b55a715 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt @@ -46,6 +46,12 @@ class AesCbcTest { iv == encrypted.initilizationVector.toHexString() } + + + } + + @Test + fun testEncryptionApi() { assertTrue { val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" val key = AesKey.Aes128Key(keyString) @@ -60,8 +66,6 @@ class AesCbcTest { ) plainText == decrypted.toHexString() } - - } @Test @@ -80,6 +84,12 @@ class AesCbcTest { expectedPlainText == decrypted.toHexString() } + + + } + + @Test + fun testDecryptionApi() { assertTrue { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" @@ -90,8 +100,8 @@ class AesCbcTest { expectedPlainText == decrypted.toHexString() } - } + } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt index 977766f..e80a995 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt @@ -49,20 +49,23 @@ class AesCtrTest { ic == encrypted.initialCounter.toHexString() } - assertTrue { - val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" - val key = AesKey.Aes128Key(keyString) - val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" + } - val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) - val decrypted = AesCtr.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initialCounter - ) + @Test + fun testEncryptionApi() { + val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" + val key = AesKey.Aes128Key(keyString) + val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" + + val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) + val decrypted = AesCtr.decrypt( + key, + encryptedDataAndInitializationVector.encryptedData, + encryptedDataAndInitializationVector.initialCounter + ) + assertTrue { plainText == decrypted.toHexString() } - } @Test @@ -81,7 +84,13 @@ class AesCtrTest { expectedPlainText == decrypted.toHexString() } - assertTrue { + + + } + + @Test + fun testCtrDecryptionApi() { + assertTrue { val key = "2b7e151628aed2a6abf7158809cf4f3c" val ic = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" val cipherText = @@ -92,6 +101,5 @@ class AesCtrTest { println("Decrypted: ${decrypted.toHexString()}") expectedPlainText == decrypted.toHexString() } - } } \ No newline at end of file diff --git a/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt b/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt index c1db5e7..0a7a85c 100644 --- a/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt +++ b/multiplatform-crypto/src/jsMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt @@ -31,6 +31,6 @@ actual object SRNG { // } else { // throw RuntimeException("Secure random not supported yet for non-nodejs environment") // } - return arrayOf((counter++).toUByte()) // TODO Wow. Such random. Very entropy. + return Array(amount) { (counter++).toUByte() } // TODO Wow. Such random. Very entropy. } } \ No newline at end of file