diff --git a/source/hw/aes.c b/source/hw/aes.c index 3850241f..8d8f136a 100644 --- a/source/hw/aes.c +++ b/source/hw/aes.c @@ -31,13 +31,17 @@ u8 aes_mode = 0; +void AES_ResetEngine(void) +{ + /* Reset Engine */ + write32(HW_AES_CMD, 0x00000000); + while ((read32(HW_AES_CMD) & AES_CMD_FLAG_EXEC) != 0); +} + void AES_EnableDecrypt(const u8 *key, const u8 *iv) { const u32 *aes_iv = (const u32*)iv; const u32 *aes_key = (const u32*)key; - /* Reset Engine */ - write32(HW_AES_CMD, 0x00000000); - while ((read32(HW_AES_CMD) & AES_CMD_FLAG_EXEC) != 0); /* write in IV and Key */ u8 i; for(i = 0; i < 4; ++i) @@ -45,14 +49,14 @@ void AES_EnableDecrypt(const u8 *key, const u8 *iv) write32(HW_AES_IV, *(aes_iv+i)); write32(HW_AES_KEY, *(aes_key+i)); } - /* set mode back to 0 */ - aes_mode = 0; } #define AES_LIMIT 0x1000 static u8 AES_BUF[AES_LIMIT*16] ATTRIBUTE_ALIGN(16); /* 64KB */ void AES_Decrypt(u8 *inbuf, u8 *outbuf, u16 num_blocks) { + /* set mode back to 0 */ + aes_mode = 0; /* split cause of limit */ u32 buf_pos = 0; u16 blocks_done = 0; diff --git a/source/hw/aes.h b/source/hw/aes.h index 3ddbe878..9aca07d9 100644 --- a/source/hw/aes.h +++ b/source/hw/aes.h @@ -17,6 +17,7 @@ #ifndef __AES_H__ #define __AES_H__ +void AES_ResetEngine(void); void AES_EnableDecrypt(const u8 *key, const u8 *iv); void AES_Decrypt(u8 *inbuf, u8 *outbuf, u16 num_blocks); diff --git a/source/libwbfs/wiidisc.c b/source/libwbfs/wiidisc.c index 7626d00d..098a84f6 100644 --- a/source/libwbfs/wiidisc.c +++ b/source/libwbfs/wiidisc.c @@ -31,15 +31,10 @@ void decrypt_title_key(u8 *tik, u8 *title_key) wbfs_memset(iv, 0, sizeof iv); wbfs_memcpy(iv, tik + 0x01dc, 8); + AES_ResetEngine(); //check byte 0x1f1 in ticket to determine whether or not to use Korean Common Key //if value = 0x01, use Korean Common Key, else just use regular one - u8 korean_flag = tik[0x01f1]; - - if(korean_flag == 1) - AES_EnableDecrypt(korean_key, iv); - else - AES_EnableDecrypt(common_key, iv); - + AES_EnableDecrypt((tik[0x01f1] == 1) ? korean_key : common_key, iv); AES_Decrypt(tik + 0x01bf, title_key, 1); } @@ -87,6 +82,7 @@ static void partition_read_block(wiidisc_t *d, u32 blockno, u8 *block) partition_raw_read(d,offset, raw, 0x8000); // decrypt data + AES_ResetEngine(); memcpy(iv, raw + 0x3d0, 16); AES_EnableDecrypt(d->disc_key, iv); AES_Decrypt(raw + 0x400, block, 0x7c0); diff --git a/source/menu/menu_wad.cpp b/source/menu/menu_wad.cpp index d6aa20c4..a3dbd55f 100644 --- a/source/menu/menu_wad.cpp +++ b/source/menu/menu_wad.cpp @@ -196,7 +196,7 @@ int installWad(const char *path) SHA1_CTX ctx; SHA1Init(&ctx); - AES_EnableDecrypt(tik_key, aes_iv); + AES_ResetEngine(); u32 size_enc_full = ALIGN(16, content->size); while(read < size_enc_full) { @@ -206,6 +206,8 @@ int installWad(const char *path) u16 num_blocks = (size_enc / 16); fread(AES_WAD_Buf, size_enc, 1, wad_file); + AES_EnableDecrypt(tik_key, aes_iv); //ISFS seems to reset it? + memcpy(aes_iv, AES_WAD_Buf+(size_enc-16), 16); //last block for cbc AES_Decrypt(AES_WAD_Buf, AES_WAD_Buf, num_blocks); u64 size_dec = (content->size - read);