Fix en/decryption of XTEA messages not a multiple of the block size

Reported by Scu11.

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 5 years ago
parent 73194bbb8d
commit 7218855eb7
  1. 8
      crypto/src/main/java/dev/openrs2/crypto/Xtea.kt
  2. 17
      crypto/src/test/java/dev/openrs2/crypto/XteaTest.kt

@ -4,11 +4,14 @@ import io.netty.buffer.ByteBuf
private const val GOLDEN_RATIO = 0x9e3779b9.toInt() private const val GOLDEN_RATIO = 0x9e3779b9.toInt()
private const val ROUNDS = 32 private const val ROUNDS = 32
private const val BLOCK_SIZE = 8
private const val BLOCK_SIZE_MASK = BLOCK_SIZE - 1
fun ByteBuf.xteaEncrypt(index: Int, length: Int, key: IntArray) { fun ByteBuf.xteaEncrypt(index: Int, length: Int, key: IntArray) {
require(key.size == 4) require(key.size == 4)
for (i in index until index + length step 8) { val end = (index + length) and BLOCK_SIZE_MASK.inv()
for (i in index until end step BLOCK_SIZE) {
var sum = 0 var sum = 0
var v0 = getInt(i) var v0 = getInt(i)
var v1 = getInt(i + 4) var v1 = getInt(i + 4)
@ -27,7 +30,8 @@ fun ByteBuf.xteaEncrypt(index: Int, length: Int, key: IntArray) {
fun ByteBuf.xteaDecrypt(index: Int, length: Int, key: IntArray) { fun ByteBuf.xteaDecrypt(index: Int, length: Int, key: IntArray) {
require(key.size == 4) require(key.size == 4)
for (i in index until index + length step 8) { val end = (index + length) and BLOCK_SIZE_MASK.inv()
for (i in index until end step BLOCK_SIZE) {
@Suppress("INTEGER_OVERFLOW") @Suppress("INTEGER_OVERFLOW")
var sum = GOLDEN_RATIO * ROUNDS var sum = GOLDEN_RATIO * ROUNDS
var v0 = getInt(i) var v0 = getInt(i)

@ -15,12 +15,27 @@ object XteaTest {
} }
private val TEST_VECTORS = listOf( private val TEST_VECTORS = listOf(
// empty
TestVector("00000000000000000000000000000000", "", ""),
// standard single block test vectors
TestVector("000102030405060708090a0b0c0d0e0f", "4142434445464748", "497df3d072612cb5"), TestVector("000102030405060708090a0b0c0d0e0f", "4142434445464748", "497df3d072612cb5"),
TestVector("000102030405060708090a0b0c0d0e0f", "4141414141414141", "e78f2d13744341d8"), TestVector("000102030405060708090a0b0c0d0e0f", "4141414141414141", "e78f2d13744341d8"),
TestVector("000102030405060708090a0b0c0d0e0f", "5a5b6e278948d77f", "4141414141414141"), TestVector("000102030405060708090a0b0c0d0e0f", "5a5b6e278948d77f", "4141414141414141"),
TestVector("00000000000000000000000000000000", "4142434445464748", "a0390589f8b8efa5"), TestVector("00000000000000000000000000000000", "4142434445464748", "a0390589f8b8efa5"),
TestVector("00000000000000000000000000000000", "4141414141414141", "ed23375a821a8c2d"), TestVector("00000000000000000000000000000000", "4141414141414141", "ed23375a821a8c2d"),
TestVector("00000000000000000000000000000000", "70e1225d6e4e7655", "4141414141414141") TestVector("00000000000000000000000000000000", "70e1225d6e4e7655", "4141414141414141"),
// two blocks
TestVector("00000000000000000000000000000000", "70e1225d6e4e76554141414141414141",
"4141414141414141ed23375a821a8c2d"),
// not a multiple of the block size
TestVector("00000000000000000000000000000000", "01", "01"),
TestVector("00000000000000000000000000000000", "01020304050607", "01020304050607"),
TestVector("00000000000000000000000000000000", "70e1225d6e4e765501", "414141414141414101"),
TestVector("00000000000000000000000000000000", "70e1225d6e4e765501020304050607",
"414141414141414101020304050607")
) )
@Test @Test

Loading…
Cancel
Save