How can I encrypt data in chunks with AES-128-CBC?
Posted: Sun Aug 11, 2013 7:04 pm
I'm currently doing a modification of BlueDump that fixes most problems present in the original application, and I want to add support for contents bigger than 45MB (like those present in the "Wii & The Internet" Channel that comes pre-installed in every new Wii).
The problem is that, in order to add support for those contents, I need to change the whole dumping process to make it write data in chunks instead of allocating memory to copy the full content data to MEM2 (yep, that's what the application originally did).
Currently, this is the code I'm using:
When I unpack the dumped title, the SHA-1 hash of the decrypted contents do not match those present on the TMD file. Please, if you have any idea, it would be greatly appreciated if you say it! Thanks in advance.
The problem is that, in order to add support for those contents, I need to change the whole dumping process to make it write data in chunks instead of allocating memory to copy the full content data to MEM2 (yep, that's what the application originally did).
Currently, this is the code I'm using:
Code: Select all
u32 GetBIGContent(FILE *f, u64 id, u16 content, u16 index, u32 size)
{
char path[ISFS_MAXPATH];
sprintf(path, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(id), TITLE_LOWER(id), content);
logfile("Regular content path is '%s'.\n", path);
printf("Adding regular content %08x.app... ", content);
s32 fd = ISFS_Open(path, ISFS_OPEN_READ);
if (fd < 0)
{
//printf("ISFS_Open for '%s' returned %d.\n", path, fd);
logfile("ISFS_Open for '%s' returned %d.\n", path, fd);
return 0;
}
u32 blksize = BLOCKSIZE; // 16KB
u8 *buffer = (u8*)memalign(32, blksize);
if (buffer == NULL)
{
//printf("Allocating memory for buffer failed.\n");
logfile("Allocating memory for buffer failed.\n");
ISFS_Close(fd);
Unmount_Devices();
Reboot();
}
u8 *encryptedcontentbuf = (u8*)memalign(32, blksize);
if (encryptedcontentbuf == NULL)
{
//printf("Allocating memory for buffer failed.\n");
logfile("Allocating memory for encryptedcontentbuf failed.\n");
ISFS_Close(fd);
Unmount_Devices();
Reboot();
}
u32 i, pad, size2 = 0;
s32 ret = 0;
logfile("Writing...\n");
for (i = 0; i < size; i += blksize)
{
if (blksize > size - i)
{
blksize = size - i;
}
ret = ISFS_Read(fd, buffer, blksize);
if (ret < 0) break;
/* Pad data to a 16-byte boundary (required for the encryption process). Probably only needed for the last chunk */
if ((blksize % 16) != 0)
{
pad = 16 - blksize % 16;
memset(&(buffer[i+blksize]), 0x00, pad);
logfile("Content chunk #%u padded to 16-byte boundary. Current blksize: %u.\n", (i / 0x4000), blksize);
blksize += pad;
}
encrypt_buffer(index, buffer, encryptedcontentbuf, blksize);
/* Pad data to a 64-byte boundary (required for the WAD alignment). Again, probably only needed for the last chunk */
if ((blksize % 64) != 0)
{
pad = 64 - blksize % 64;
memset(&(encryptedcontentbuf[i+blksize]), 0x00, pad);
logfile("Encrypted content chunk #%u padded to 64-byte boundary. Current blksize: %u.\n", (i / 0x4000), blksize);
blksize += pad;
}
fwrite(encryptedcontentbuf, 1, blksize, f);
size2 += blksize;
}
logfile("Content added successfully. Original content size: %u bytes. size2: %u bytes.\n", size, size2);
free(buffer);
free(encryptedcontentbuf);
ISFS_Close(fd);
if (ret < 0)
{
//printf("Failed to read data into content buffer.");
logfile("Failed to read data into content buffer.");
fclose(f);
Unmount_Devices();
Reboot();
}
printf("done.\n");
header->data_len += size2;
return size2;
}