Fix missing leading zeroes in counter

This commit is contained in:
Ugljesa Jovanovic 2019-09-24 00:52:49 +02:00 committed by Ugljesa Jovanovic
parent ec3b87db49
commit d8ea3d2693
No known key found for this signature in database
GPG Key ID: 33A5F353387711A5
7 changed files with 63 additions and 32 deletions

View File

@ -149,8 +149,6 @@ kotlin {
}
val nativeMain by creating {
dependsOn(commonMain)
dependencies {
}
}
val nativeTest by creating {

View File

@ -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 ->
Array<UByte>(4) { innerCounter -> input[innerCounter * 4 + outerCounter] }
}.toTypedArray()

View File

@ -97,7 +97,11 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
var currentOutput: 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() }
@ -158,7 +162,7 @@ class AesCbc internal constructor(val aesKey: AesKey, val mode: Mode, initializa
}
return EncryptedDataAndInitializationVector(
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) {
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
}

View File

@ -78,7 +78,11 @@ class AesCtr internal constructor(val aesKey: AesKey, val mode: Mode, initialCou
var currentOutput: 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))
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> {
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<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

View File

@ -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()
}
}
}

View File

@ -49,7 +49,10 @@ class AesCtrTest {
ic == encrypted.initialCounter.toHexString()
}
assertTrue {
}
@Test
fun testEncryptionApi() {
val keyString = "4278b840fb44aaa757c1bf04acbe1a3e"
val key = AesKey.Aes128Key(keyString)
val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
@ -60,9 +63,9 @@ class AesCtrTest {
encryptedDataAndInitializationVector.encryptedData,
encryptedDataAndInitializationVector.initialCounter
)
assertTrue {
plainText == decrypted.toHexString()
}
}
@Test
@ -81,6 +84,12 @@ class AesCtrTest {
expectedPlainText == decrypted.toHexString()
}
}
@Test
fun testCtrDecryptionApi() {
assertTrue {
val key = "2b7e151628aed2a6abf7158809cf4f3c"
val ic = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
@ -92,6 +101,5 @@ class AesCtrTest {
println("Decrypted: ${decrypted.toHexString()}")
expectedPlainText == decrypted.toHexString()
}
}
}

View File

@ -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<UByte>(amount) { (counter++).toUByte() } // TODO Wow. Such random. Very entropy.
}
}