Fix missing leading zeroes in counter
This commit is contained in:
parent
ec3b87db49
commit
d8ea3d2693
@ -149,8 +149,6 @@ kotlin {
|
|||||||
}
|
}
|
||||||
val nativeMain by creating {
|
val nativeMain by creating {
|
||||||
dependsOn(commonMain)
|
dependsOn(commonMain)
|
||||||
dependencies {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val nativeTest by creating {
|
val nativeTest by creating {
|
||||||
|
|
||||||
|
@ -64,12 +64,6 @@ internal class Aes internal constructor(val aesKey: AesKey, val input: Array<UBy
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
if (input.size != 16) {
|
|
||||||
throw RuntimeException("Invalid input size ${input.size}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val state: Array<Array<UByte>> = (0 until 4).map { outerCounter ->
|
val state: Array<Array<UByte>> = (0 until 4).map { outerCounter ->
|
||||||
Array<UByte>(4) { innerCounter -> input[innerCounter * 4 + outerCounter] }
|
Array<UByte>(4) { innerCounter -> input[innerCounter * 4 + outerCounter] }
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
@ -97,7 +97,11 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
|
|||||||
|
|
||||||
var currentOutput: Array<UByte> = arrayOf()
|
var currentOutput: Array<UByte> = arrayOf()
|
||||||
var previousEncrypted: Array<UByte> = arrayOf()
|
var previousEncrypted: Array<UByte> = arrayOf()
|
||||||
val iv = initializationVector ?: SRNG.getRandomBytes(16)
|
val initVector = if (initializationVector.isNullOrEmpty()) {
|
||||||
|
SRNG.getRandomBytes(16)
|
||||||
|
} else {
|
||||||
|
initializationVector
|
||||||
|
}
|
||||||
|
|
||||||
val output = MutableList<Array<UByte>>(0) { arrayOf() }
|
val output = MutableList<Array<UByte>>(0) { arrayOf() }
|
||||||
|
|
||||||
@ -158,7 +162,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
|
|||||||
}
|
}
|
||||||
return EncryptedDataAndInitializationVector(
|
return EncryptedDataAndInitializationVector(
|
||||||
output.reversed().foldRight(Array<UByte>(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes },
|
output.reversed().foldRight(Array<UByte>(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) {
|
return when (mode) {
|
||||||
Mode.ENCRYPT -> {
|
Mode.ENCRYPT -> {
|
||||||
currentOutput = if (currentOutput.isEmpty()) {
|
currentOutput = if (currentOutput.isEmpty()) {
|
||||||
Aes.encrypt(aesKey, data xor iv)
|
println("IV: $initVector")
|
||||||
|
Aes.encrypt(aesKey, data xor initVector)
|
||||||
} else {
|
} else {
|
||||||
Aes.encrypt(aesKey, data xor currentOutput)
|
Aes.encrypt(aesKey, data xor currentOutput)
|
||||||
}
|
}
|
||||||
@ -201,7 +206,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
|
|||||||
}
|
}
|
||||||
Mode.DECRYPT -> {
|
Mode.DECRYPT -> {
|
||||||
if (currentOutput.isEmpty()) {
|
if (currentOutput.isEmpty()) {
|
||||||
currentOutput = Aes.decrypt(aesKey, data) xor iv
|
currentOutput = Aes.decrypt(aesKey, data) xor initVector
|
||||||
} else {
|
} else {
|
||||||
currentOutput = Aes.decrypt(aesKey, data) xor previousEncrypted
|
currentOutput = Aes.decrypt(aesKey, data) xor previousEncrypted
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,11 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
|
|||||||
|
|
||||||
var currentOutput: Array<UByte> = arrayOf()
|
var currentOutput: Array<UByte> = arrayOf()
|
||||||
var previousEncrypted: Array<UByte> = arrayOf()
|
var previousEncrypted: Array<UByte> = 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))
|
var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Endianness.BIG))
|
||||||
|
|
||||||
val output = MutableList<Array<UByte>>(0) { arrayOf() }
|
val output = MutableList<Array<UByte>>(0) { arrayOf() }
|
||||||
@ -158,17 +162,29 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun consumeBlock(data: Array<UByte>, blockCount: ModularBigInteger): Array<UByte> {
|
private fun consumeBlock(data: Array<UByte>, blockCount: ModularBigInteger): Array<UByte> {
|
||||||
|
val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes()
|
||||||
return when (mode) {
|
return when (mode) {
|
||||||
Mode.ENCRYPT -> {
|
Mode.ENCRYPT -> {
|
||||||
Aes.encrypt(aesKey, blockCount.toUByteArray(Endianness.BIG)) xor data
|
Aes.encrypt(aesKey, blockCountAsByteArray) xor data
|
||||||
}
|
}
|
||||||
Mode.DECRYPT -> {
|
Mode.DECRYPT -> {
|
||||||
Aes.encrypt(aesKey, blockCount.toUByteArray(Endianness.BIG)) xor data
|
Aes.encrypt(aesKey, blockCountAsByteArray) xor data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Array<UByte>.expandCounterTo16Bytes() : Array<UByte> {
|
||||||
|
return if (this.size < 16) {
|
||||||
|
println("Expanding")
|
||||||
|
val diff = 16 - this.size
|
||||||
|
val pad = Array<UByte>(diff) { 0U }
|
||||||
|
pad + this
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
|
@ -46,6 +46,12 @@ class AesCbcTest {
|
|||||||
iv == encrypted.initilizationVector.toHexString()
|
iv == encrypted.initilizationVector.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEncryptionApi() {
|
||||||
assertTrue {
|
assertTrue {
|
||||||
val keyString = "4278b840fb44aaa757c1bf04acbe1a3e"
|
val keyString = "4278b840fb44aaa757c1bf04acbe1a3e"
|
||||||
val key = AesKey.Aes128Key(keyString)
|
val key = AesKey.Aes128Key(keyString)
|
||||||
@ -60,8 +66,6 @@ class AesCbcTest {
|
|||||||
)
|
)
|
||||||
plainText == decrypted.toHexString()
|
plainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -80,6 +84,12 @@ class AesCbcTest {
|
|||||||
expectedPlainText == decrypted.toHexString()
|
expectedPlainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDecryptionApi() {
|
||||||
assertTrue {
|
assertTrue {
|
||||||
val key = "4278b840fb44aaa757c1bf04acbe1a3e"
|
val key = "4278b840fb44aaa757c1bf04acbe1a3e"
|
||||||
val iv = "57f02a5c5339daeb0a2908a06ac6393f"
|
val iv = "57f02a5c5339daeb0a2908a06ac6393f"
|
||||||
@ -90,8 +100,8 @@ class AesCbcTest {
|
|||||||
|
|
||||||
expectedPlainText == decrypted.toHexString()
|
expectedPlainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -49,7 +49,10 @@ class AesCtrTest {
|
|||||||
ic == encrypted.initialCounter.toHexString()
|
ic == encrypted.initialCounter.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue {
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEncryptionApi() {
|
||||||
val keyString = "4278b840fb44aaa757c1bf04acbe1a3e"
|
val keyString = "4278b840fb44aaa757c1bf04acbe1a3e"
|
||||||
val key = AesKey.Aes128Key(keyString)
|
val key = AesKey.Aes128Key(keyString)
|
||||||
val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
|
val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
|
||||||
@ -60,9 +63,9 @@ class AesCtrTest {
|
|||||||
encryptedDataAndInitializationVector.encryptedData,
|
encryptedDataAndInitializationVector.encryptedData,
|
||||||
encryptedDataAndInitializationVector.initialCounter
|
encryptedDataAndInitializationVector.initialCounter
|
||||||
)
|
)
|
||||||
|
assertTrue {
|
||||||
plainText == decrypted.toHexString()
|
plainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -81,6 +84,12 @@ class AesCtrTest {
|
|||||||
expectedPlainText == decrypted.toHexString()
|
expectedPlainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCtrDecryptionApi() {
|
||||||
assertTrue {
|
assertTrue {
|
||||||
val key = "2b7e151628aed2a6abf7158809cf4f3c"
|
val key = "2b7e151628aed2a6abf7158809cf4f3c"
|
||||||
val ic = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
|
val ic = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
|
||||||
@ -92,6 +101,5 @@ class AesCtrTest {
|
|||||||
println("Decrypted: ${decrypted.toHexString()}")
|
println("Decrypted: ${decrypted.toHexString()}")
|
||||||
expectedPlainText == decrypted.toHexString()
|
expectedPlainText == decrypted.toHexString()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,6 +31,6 @@ actual object SRNG {
|
|||||||
// } else {
|
// } else {
|
||||||
// throw RuntimeException("Secure random not supported yet for non-nodejs environment")
|
// throw RuntimeException("Secure random not supported yet for non-nodejs environment")
|
||||||
// }
|
// }
|
||||||
return arrayOf((counter++).toUByte()) // TODO Wow. Such random. Very entropy.
|
return Array<UByte>(amount) { (counter++).toUByte() } // TODO Wow. Such random. Very entropy.
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user