Skip to content

Commit

Permalink
fix buffer sizes in cipher utils
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermarian committed Dec 30, 2023
1 parent cef8153 commit 5b86dfd
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
2 changes: 1 addition & 1 deletion driver/src/main/java/studio/driver/fs/AESCBCCipher.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static byte[] decipher(byte[] bytes, FsDeviceKeyV3 deviceKeyV3) {
}

private static byte[] cbc(byte[] bytes, FsDeviceKeyV3 deviceKeyV3, int mode) {
// Zero-bytes padding
// Zero-bytes padding (keeping the padding when deciphering should be OK if that's what the firmware expects anyway)
int incompleteBlockLength = bytes.length % AES_CBC_BLOCK_SIZE;
if (incompleteBlockLength > 0) {
int paddingLength = AES_CBC_BLOCK_SIZE - incompleteBlockLength;
Expand Down
49 changes: 30 additions & 19 deletions driver/src/main/java/studio/driver/fs/CipherUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
*/
public class CipherUtils {

private static final int CIPHER_BLOCK_SIZE_BOOT_V2 = 64;
private static final int CIPHER_BLOCK_SIZE_ASSETS_V2 = 512;
private static final int CIPHER_BLOCK_SIZE_ASSETS_V3 = 512;

private static final String NODE_INDEX_FILENAME = "ni";
private static final String LIST_INDEX_FILENAME = "li";
private static final String IMAGE_INDEX_FILENAME = "ri";
Expand All @@ -57,7 +61,7 @@ static void addBootFileV2(Path packFolder, byte[] deviceUuid) throws IOException
byte[] specificKey = computeSpecificKeyV2FromUUID(deviceUuid);
// Read ciphered block of ri file
FileInputStream riFis = new FileInputStream(new File(packFolder.toFile(), IMAGE_INDEX_FILENAME));
byte[] riCipheredBlock = riFis.readNBytes(64);
byte[] riCipheredBlock = riFis.readNBytes(CIPHER_BLOCK_SIZE_BOOT_V2);
riFis.close();
// Add boot file: bt
FileOutputStream btFos = new FileOutputStream(new File(packFolder.toFile(), BOOT_FILENAME));
Expand All @@ -73,26 +77,26 @@ static void addBootFileV3(Path packFolder, FsDeviceKeyV3 deviceKeyV3) throws IOE
}

static byte[] cipherFirstBlockCommonKey(byte[] data) {
byte[] block = Arrays.copyOfRange(data, 0, Math.min(512, data.length));
byte[] block = Arrays.copyOfRange(data, 0, Math.min(CIPHER_BLOCK_SIZE_ASSETS_V2, data.length));
int[] dataInt = BytesUtils.toIntArray(block, ByteOrder.LITTLE_ENDIAN);
int[] encryptedInt = XXTEACipher.btea(dataInt, Math.min(128, data.length/4), BytesUtils.toIntArray(XXTEACipher.COMMON_KEY, ByteOrder.BIG_ENDIAN));
int[] encryptedInt = XXTEACipher.btea(dataInt, Math.min(CIPHER_BLOCK_SIZE_ASSETS_V2/4, data.length/4), BytesUtils.toIntArray(XXTEACipher.COMMON_KEY, ByteOrder.BIG_ENDIAN));
byte[] encryptedBlock = BytesUtils.toByteArray(encryptedInt, ByteOrder.LITTLE_ENDIAN);
ByteBuffer bb = ByteBuffer.allocate(data.length);
bb.put(encryptedBlock);
if (data.length > 512) {
bb.put(Arrays.copyOfRange(data, 512, data.length));
if (data.length > CIPHER_BLOCK_SIZE_ASSETS_V2) {
bb.put(Arrays.copyOfRange(data, CIPHER_BLOCK_SIZE_ASSETS_V2, data.length));
}
return bb.array();
}
static byte[] decipherFirstBlockCommonKey(byte[] data) {
byte[] block = Arrays.copyOfRange(data, 0, Math.min(512, data.length));
byte[] block = Arrays.copyOfRange(data, 0, Math.min(CIPHER_BLOCK_SIZE_ASSETS_V2, data.length));
int[] dataInt = BytesUtils.toIntArray(block, ByteOrder.LITTLE_ENDIAN);
int[] decryptedInt = XXTEACipher.btea(dataInt, -(Math.min(128, data.length/4)), BytesUtils.toIntArray(XXTEACipher.COMMON_KEY, ByteOrder.BIG_ENDIAN));
int[] decryptedInt = XXTEACipher.btea(dataInt, -(Math.min(CIPHER_BLOCK_SIZE_ASSETS_V2/4, data.length/4)), BytesUtils.toIntArray(XXTEACipher.COMMON_KEY, ByteOrder.BIG_ENDIAN));
byte[] decryptedBlock = BytesUtils.toByteArray(decryptedInt, ByteOrder.LITTLE_ENDIAN);
ByteBuffer bb = ByteBuffer.allocate(data.length);
bb.put(decryptedBlock);
if (data.length > 512) {
bb.put(Arrays.copyOfRange(data, 512, data.length));
if (data.length > CIPHER_BLOCK_SIZE_ASSETS_V2) {
bb.put(Arrays.copyOfRange(data, CIPHER_BLOCK_SIZE_ASSETS_V2, data.length));
}
return bb.array();
}
Expand All @@ -107,29 +111,36 @@ private static byte[] computeSpecificKeyV2FromUUID(byte[] uuid) {
return reorderedBtKey;
}
static byte[] cipherFirstBlockSpecificKeyV2(byte[] data, byte[] specificKey) {
byte[] block = Arrays.copyOfRange(data, 0, Math.min(64, data.length));
byte[] block = Arrays.copyOfRange(data, 0, Math.min(CIPHER_BLOCK_SIZE_BOOT_V2, data.length));
int[] dataInt = BytesUtils.toIntArray(block, ByteOrder.LITTLE_ENDIAN);
int[] encryptedInt = XXTEACipher.btea(dataInt, Math.min(128, data.length/4), BytesUtils.toIntArray(specificKey, ByteOrder.BIG_ENDIAN));
return BytesUtils.toByteArray(encryptedInt, ByteOrder.LITTLE_ENDIAN);
int[] encryptedInt = XXTEACipher.btea(dataInt, Math.min(CIPHER_BLOCK_SIZE_BOOT_V2/4, data.length/4), BytesUtils.toIntArray(specificKey, ByteOrder.BIG_ENDIAN));
byte[] encryptedBlock = BytesUtils.toByteArray(encryptedInt, ByteOrder.LITTLE_ENDIAN);
ByteBuffer bb = ByteBuffer.allocate(data.length);
bb.put(encryptedBlock);
if (data.length > CIPHER_BLOCK_SIZE_BOOT_V2) {
bb.put(Arrays.copyOfRange(data, CIPHER_BLOCK_SIZE_BOOT_V2, data.length));
}
return bb.array();
}

static byte[] cipherFirstBlockSpecificKeyV3(byte[] data, FsDeviceKeyV3 deviceKeyV3) {
byte[] block = Arrays.copyOfRange(data, 0, Math.min(512, data.length));
byte[] block = Arrays.copyOfRange(data, 0, Math.min(CIPHER_BLOCK_SIZE_ASSETS_V3, data.length));
byte[] encryptedBlock = AESCBCCipher.cipher(block, deviceKeyV3);
ByteBuffer bb = ByteBuffer.allocate(data.length);
int outputLength = encryptedBlock.length + Math.max(0, data.length - CIPHER_BLOCK_SIZE_ASSETS_V3);
ByteBuffer bb = ByteBuffer.allocate(outputLength);
bb.put(encryptedBlock);
if (data.length > 512) {
bb.put(Arrays.copyOfRange(data, 512, data.length));
if (data.length > CIPHER_BLOCK_SIZE_ASSETS_V3) {
bb.put(Arrays.copyOfRange(data, CIPHER_BLOCK_SIZE_ASSETS_V3, data.length));
}
return bb.array();
}
static byte[] decipherFirstBlockSpecificKeyV3(byte[] data, FsDeviceKeyV3 deviceKeyV3) {
byte[] block = Arrays.copyOfRange(data, 0, Math.min(512, data.length));
byte[] block = Arrays.copyOfRange(data, 0, Math.min(CIPHER_BLOCK_SIZE_ASSETS_V3, data.length));
byte[] decryptedBlock = AESCBCCipher.decipher(block, deviceKeyV3);
ByteBuffer bb = ByteBuffer.allocate(data.length);
bb.put(decryptedBlock);
if (data.length > 512) {
bb.put(Arrays.copyOfRange(data, 512, data.length));
if (data.length > CIPHER_BLOCK_SIZE_ASSETS_V3) {
bb.put(Arrays.copyOfRange(data, CIPHER_BLOCK_SIZE_ASSETS_V3, data.length));
}
return bb.array();
}
Expand Down

0 comments on commit 5b86dfd

Please sign in to comment.