mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 09:05:06 +01:00
95 lines
2.9 KiB
C
95 lines
2.9 KiB
C
/****************************************************************************
|
|
* Copyright (C) 2013 FIX94
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
****************************************************************************/
|
|
#include <string.h>
|
|
#include <gctypes.h>
|
|
#include <malloc.h>
|
|
#include <ogc/cache.h>
|
|
#include <ogc/system.h>
|
|
#include <ogc/machine/processor.h>
|
|
#include "loader/utils.h"
|
|
#include "memory/memory.h"
|
|
#include "aes.h"
|
|
|
|
#define AES_CMD_FLAG_EXEC (1<<31)
|
|
#define AES_CMD_FLAG_ENA (1<<28)
|
|
#define AES_CMD_FLAG_DEC (1<<27)
|
|
#define AES_CMD_FLAG_IV (1<<12)
|
|
|
|
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;
|
|
/* write in IV and Key */
|
|
u8 i;
|
|
for(i = 0; i < 4; ++i)
|
|
{
|
|
write32(HW_AES_IV, *(aes_iv+i));
|
|
write32(HW_AES_KEY, *(aes_key+i));
|
|
}
|
|
}
|
|
|
|
#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;
|
|
u32 buf_done = 0;
|
|
u16 blocks_full = num_blocks;
|
|
while(blocks_done < blocks_full)
|
|
{
|
|
/* Calculate Position */
|
|
blocks_done = blocks_full;
|
|
if(blocks_done > AES_LIMIT)
|
|
blocks_done = AES_LIMIT;
|
|
buf_done = blocks_done * 16;
|
|
/* Copy into our aligned buffer */
|
|
memcpy(AES_BUF, (inbuf + buf_pos), buf_done);
|
|
/* Flush and Invalidate */
|
|
DCFlushRange(AES_BUF, buf_done);
|
|
ICInvalidateRange(AES_BUF, buf_done);
|
|
/* set location */
|
|
write32(HW_AES_SRC, (u32)MEM_VIRTUAL_TO_PHYSICAL(AES_BUF));
|
|
write32(HW_AES_DEST, (u32)MEM_VIRTUAL_TO_PHYSICAL(AES_BUF));
|
|
/* enable engine, set size, set iv flag and enable decryption */
|
|
write32(HW_AES_CMD, AES_CMD_FLAG_ENA | AES_CMD_FLAG_DEC | AES_CMD_FLAG_EXEC |
|
|
((aes_mode == 0) ? 0 : AES_CMD_FLAG_IV) | (blocks_done - 1));
|
|
while (read32(HW_AES_CMD) & AES_CMD_FLAG_EXEC);
|
|
/* set down num blocks */
|
|
blocks_full -= blocks_done;
|
|
/* increase aes mode to keep iv */
|
|
if(aes_mode == 0) aes_mode++;
|
|
/* flush and write outbuf */
|
|
DCFlushRange(AES_BUF, buf_done);
|
|
memcpy((outbuf + buf_pos), AES_BUF, buf_done);
|
|
/* increase block pos */
|
|
buf_pos += buf_done;
|
|
}
|
|
}
|