mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@76 4ee2a332-4b2b-5046-8439-1ba90f034370
2267 lines
72 KiB
C
2267 lines
72 KiB
C
/*---------------------------------------------------------------------------*
|
|
Project: TwlSDK - library - aes
|
|
File: aes.c
|
|
|
|
Copyright 2007 Nintendo. All rights reserved.
|
|
|
|
These coded instructions, statements, and computer programs contain
|
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
|
Company Ltd., and are protected by Federal copyright law. They may
|
|
not be disclosed to third parties or copied or duplicated in any form,
|
|
in whole or in part, without the prior written consent of Nintendo.
|
|
|
|
$Log: $
|
|
$NoKeywords: $
|
|
*---------------------------------------------------------------------------*/
|
|
#include <twl.h>
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
定数定義
|
|
*---------------------------------------------------------------------------*/
|
|
// 詰めてコピーする
|
|
#define AES_PACK_U32(d, s) \
|
|
((d)[0] = (u8)((*((u32*)s) >> 0) & 0xFF), \
|
|
(d)[1] = (u8)((*((u32*)s) >> 8) & 0xFF), \
|
|
(d)[2] = (u8)((*((u32*)s) >> 16) & 0xFF), \
|
|
(d)[3] = (u8)((*((u32*)s) >> 24) & 0xFF))
|
|
|
|
#define AES_PACK_U96(d, s) \
|
|
(AES_PACK_U32((d) + 0, ((u96*)s)->e + 0), \
|
|
AES_PACK_U32((d) + 4, ((u96*)s)->e + 1), \
|
|
AES_PACK_U32((d) + 8, ((u96*)s)->e + 2))
|
|
|
|
#define AES_PACK_U128(d, s) \
|
|
(AES_PACK_U32((d) + 0, ((u128*)s)->e + 0), \
|
|
AES_PACK_U32((d) + 4, ((u128*)s)->e + 1), \
|
|
AES_PACK_U32((d) + 8, ((u128*)s)->e + 2), \
|
|
AES_PACK_U32((d) + 12, ((u128*)s)->e + 3))
|
|
|
|
// データ数を設定する
|
|
#define AES_SUBSEQUENT_NUMS(a) (((a) << AES_PXI_SUBSEQUENT_NUMS_SHIFT) & AES_PXI_SUBSEQUENT_NUMS_MASK)
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
型定義
|
|
*---------------------------------------------------------------------------*/
|
|
typedef struct AESWork
|
|
{
|
|
BOOL lock;
|
|
AESCallback callback;
|
|
AESResult result;
|
|
void *callbackArg;
|
|
}
|
|
AESWork;
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
静的変数定義
|
|
*---------------------------------------------------------------------------*/
|
|
static BOOL aesInitialized;
|
|
static AESWork aesWork;
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
内部関数定義
|
|
*---------------------------------------------------------------------------*/
|
|
static BOOL AesSendPxiCommand(AESPxiCommand command, u8 size, u8 data);
|
|
static BOOL AesSendPxiData(u8 *pData);
|
|
static void AesPxiCallback(PXIFifoTag tag, u32 data, BOOL err);
|
|
static void AesSyncCallback(AESResult result, void *arg);
|
|
static void AesCallCallbackAndUnlock(AESResult result);
|
|
static void AesWaitBusy(void);
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_Init
|
|
|
|
Description: AESライブラリを初期化する。
|
|
|
|
Arguments: None.
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void AES_Init(void)
|
|
{
|
|
// 初期化済みを確認
|
|
if (aesInitialized)
|
|
{
|
|
return;
|
|
}
|
|
aesInitialized = 1;
|
|
|
|
// 変数初期化
|
|
aesWork.lock = FALSE;
|
|
aesWork.callback = NULL;
|
|
|
|
// PXI関連を初期化
|
|
PXI_Init();
|
|
while (!PXI_IsCallbackReady(PXI_FIFO_TAG_AES, PXI_PROC_ARM7))
|
|
{
|
|
}
|
|
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_AES, AesPxiCallback);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_ResetAsync
|
|
|
|
Description: stop and reset AES block. but key resisters do not clear.
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_ResetAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_RESET;
|
|
const u8 size = AES_PXI_SIZE_RESET;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_Reset
|
|
|
|
Description: stop and reset AES block. but key resisters do not clear.
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_Reset(void)
|
|
{
|
|
aesWork.result = AES_ResetAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_IsBusyAsync
|
|
|
|
Description: check whether AES is busy or not
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_IsBusyAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_IS_BUSY;
|
|
const u8 size = AES_PXI_SIZE_IS_BUSY;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_IsBusy
|
|
|
|
Description: check whether AES is busy or not
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_IsBusy(void)
|
|
{
|
|
aesWork.result = AES_IsBusyAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitAsync
|
|
|
|
Description: wait while AES is busy
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_WAIT;
|
|
const u8 size = AES_PXI_SIZE_WAIT;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_Wait
|
|
|
|
Description: wait while AES is busy
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_Wait(void)
|
|
{
|
|
aesWork.result = AES_WaitAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_InputFifoIsFullAsync
|
|
|
|
Description: check whether AES input fifo is full or not
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_InputFifoIsFullAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_INPUT_FIFO_IS_FULL;
|
|
const u8 size = AES_PXI_SIZE_INPUT_FIFO_IS_FULL;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_InputFifoIsFull
|
|
|
|
Description: check whether AES input fifo is full or not
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_InputFifoIsFull(void)
|
|
{
|
|
aesWork.result = AES_InputFifoIsFullAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_OutputFifoIsEmptyAsync
|
|
|
|
Description: check whether AES output fifo is empty or not
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_OutputFifoIsEmptyAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_OUTPUT_FIFO_IS_EMPTY;
|
|
const u8 size = AES_PXI_SIZE_OUTPUT_FIFO_IS_EMPTY;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_OutputFifoIsEmpty
|
|
|
|
Description: check whether AES output fifo is empty or not
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_OutputFifoIsEmpty(void)
|
|
{
|
|
aesWork.result = AES_OutputFifoIsEmptyAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitInputFifoNotFullAsync
|
|
|
|
Description: wait while AES input fifo is full.
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitInputFifoNotFullAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_WAIT_INPUT_FIFO_NOT_FULL;
|
|
const u8 size = AES_PXI_SIZE_WAIT_INPUT_FIFO_NOT_FULL;
|
|
OSIntrMode enabled;
|
|
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitInputFifoNotFull
|
|
|
|
Description: wait while AES input fifo is full.
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitInputFifoNotFull(void)
|
|
{
|
|
aesWork.result = AES_WaitInputFifoNotFullAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitOutputFifoNotEmptyAsync
|
|
|
|
Description: wait while AES output fifo is empty.
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitOutputFifoNotEmptyAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_WAIT_OUTPUT_FIFO_NOT_EMPTY;
|
|
const u8 size = AES_PXI_SIZE_WAIT_OUTPUT_FIFO_NOT_EMPTY;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitOutputFifoNotEmpty
|
|
|
|
Description: wait while AES output fifo is empty.
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitOutputFifoNotEmpty(void)
|
|
{
|
|
aesWork.result = AES_WaitOutputFifoNotEmptyAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_IsValidAsync
|
|
|
|
Description: check whether CCM decryption is valid or not.
|
|
it may return TRUE just after CCM decryption has been completed.
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_IsValidAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_IS_VALID;
|
|
const u8 size = AES_PXI_SIZE_IS_VALID;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_IsValid
|
|
|
|
Description: check whether CCM decryption is valid or not.
|
|
it may return TRUE just after CCM decryption has been completed.
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_IsValid(void)
|
|
{
|
|
aesWork.result = AES_IsValidAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
#if 0
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SelectKeyAsync
|
|
|
|
Description: select key from one of four key registers
|
|
Note: SHOULD be called after AES_Set*() prior to AES_Start*().
|
|
async version
|
|
|
|
Arguments: keyNo - key group number.
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SelectKeyAsync(u32 keyNo, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SELECT_KEY;
|
|
const u8 size = AES_PXI_SIZE_SELECT_KEY;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, (u8)keyNo) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SelectKey
|
|
|
|
Description: select key from one of four key registers
|
|
Note: SHOULD be called after AES_Set*() prior to AES_Start*().
|
|
sync version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SelectKey(u32 keyNo)
|
|
{
|
|
aesWork.result = AES_SelectKeyAsync(keyNo, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetKeyAsync
|
|
|
|
Description: set key data into key register
|
|
Note: SHOULD be called after AES_Set*() prior to AES_Start*().
|
|
async version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetKeyAsync(u32 keyNo, const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
AES_ASSERT_KEYNO(keyNo);
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)keyNo;
|
|
AES_PACK_U128(&data[1], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetKey
|
|
|
|
Description: set key data into key register
|
|
sync version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetKey(u32 keyNo, const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetKeyAsync(keyNo, pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetIdAsync
|
|
|
|
Description: set id data into id register
|
|
Note: never set key register with id and seed
|
|
async version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pId - pointer to id data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetIdAsync(u32 keyNo, const u128 *pId, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_ID;
|
|
const u8 size = AES_PXI_SIZE_SET_ID;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
AES_ASSERT_KEYNO(keyNo);
|
|
SDK_NULL_ASSERT(pId);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)keyNo;
|
|
AES_PACK_U128(&data[1], pId);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetId
|
|
|
|
Description: set id data into id register
|
|
Note: never set key register with id and seed
|
|
sync version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pId - pointer to id data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetId(u32 keyNo, const u128 *pId)
|
|
{
|
|
aesWork.result = AES_SetIdAsync(keyNo, pId, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSeedAsync
|
|
|
|
Description: set id data into id register
|
|
Note: automatically set associated key register with id and seed
|
|
async version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pSeed - pointer to seed data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSeedAsync(u32 keyNo, const u128 *pSeed, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_SEED;
|
|
const u8 size = AES_PXI_SIZE_SET_SEED;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
AES_ASSERT_KEYNO(keyNo);
|
|
SDK_NULL_ASSERT(pSeed);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)keyNo;
|
|
AES_PACK_U128(&data[1], pSeed);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSeed
|
|
|
|
Description: set id data into id register
|
|
Note: automatically set associated key register with id and seed
|
|
sync version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pSeed - pointer to seed data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSeed(u32 keyNo, const u128 *pSeed)
|
|
{
|
|
aesWork.result = AES_SetSeedAsync(keyNo, pSeed, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetKey2Async
|
|
|
|
Description: set seed/id data into seed/id register
|
|
Note: automatically set associated key register with id and seed
|
|
async version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pId - pointer to id data
|
|
pSeed - pointer to seed data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetKey2Async(u32 keyNo, const u128 *pId, const u128 *pSeed, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_KEY2;
|
|
const u8 size = AES_PXI_SIZE_SET_KEY2;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
AES_ASSERT_KEYNO(keyNo);
|
|
SDK_NULL_ASSERT(pId);
|
|
SDK_NULL_ASSERT(pSeed);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)keyNo;
|
|
AES_PACK_U128(&data[1], pId);
|
|
AES_PACK_U128(&data[17], pSeed);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetKey2
|
|
|
|
Description: set seed/id data into seed/id register
|
|
Note: automatically set associated key register with id and seed
|
|
sync version.
|
|
|
|
Arguments: keyNo - key group number.
|
|
pId - pointer to id data
|
|
pSeed - pointer to seed data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetKey2(u32 keyNo, const u128 *pId, const u128 *pSeed)
|
|
{
|
|
aesWork.result = AES_SetKey2Async(keyNo, pId, pSeed, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
#else
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetGeneralKeyAsync
|
|
|
|
Description: set AES key normally
|
|
|
|
Arguments: pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetGeneralKeyAsync(const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_GENERAL_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_GENERAL_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetGeneralKey
|
|
|
|
Description: set AES key normally
|
|
sync version.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetGeneralKey(const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetGeneralKeyAsync(pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSystemKeyAsync
|
|
|
|
Description: set AES key to be restricted to the system (device)
|
|
NOTE: if data encrypted this key, other system cannot
|
|
decrypt with this key. but another key can decrypt it if
|
|
another key was found for another system.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSystemKeyAsync(const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_SYSTEM_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_SYSTEM_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSystemKey
|
|
|
|
Description: set AES key to be restricted to the system (device)
|
|
NOTE: if data encrypted this key, other system cannot
|
|
decrypt with this key. but another key can decrypt it if
|
|
another key was found for another system.
|
|
sync version.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSystemKey(const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetSystemKeyAsync(pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetGameKeyAsync
|
|
|
|
Description: set AES key to be restricted to the application (initial code).
|
|
NOTE: if data encrypted this key, other application cannot
|
|
decrypt with this key. but another key can decrypt it if
|
|
another key was found for another application.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetGameKeyAsync(const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_GAME_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_GAME_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetGameKey
|
|
|
|
Description: set AES key to be restricted to the application (initial code).
|
|
NOTE: if data encrypted this key, other application cannot
|
|
decrypt with this key. but another key can decrypt it if
|
|
another key was found for another application.
|
|
sync version.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetGameKey(const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetGameKeyAsync(pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSpecialKeyAsync
|
|
|
|
Description: set AES key to be restricted to the application and the system.
|
|
NOTE: if data encrypted this key, other application or other
|
|
system cannot decrypt with this key. but another key can
|
|
decrypt it if another key was found for another application
|
|
and/or another system.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSpecialKeyAsync(const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_SPECIAL_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_SPECIAL_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetSpecialKey
|
|
|
|
Description: set AES key to be restricted to the application and the system.
|
|
NOTE: if data encrypted this key, other application or other
|
|
system cannot decrypt with this key. but another key can
|
|
decrypt it if another key was found for another application
|
|
and/or another system.
|
|
sync version.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetSpecialKey(const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetSpecialKeyAsync(pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
#if 0 // for loader
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AESi_SetAlternativeKeyAsync
|
|
|
|
Description: set mangled AES key
|
|
|
|
Arguments: pKey - pointer to key data
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AESi_SetAlternativeKeyAsync(const u128 *pKey, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_SET_ALTERNATIVE_KEY;
|
|
const u8 size = AES_PXI_SIZE_SET_ALTERNATIVE_KEY;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(pKey);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], pKey);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_SetAlternativeKey
|
|
|
|
Description: set mangled AES key
|
|
sync version.
|
|
|
|
Arguments: pKey - pointer to key data
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_SetAlternativeKey(const u128 *pKey)
|
|
{
|
|
aesWork.result = AES_SetAlternativeKeyAsync(pKey, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCcmDecAsync
|
|
|
|
Description: start AES engine for AES-CCM decryption.
|
|
async version.
|
|
|
|
Arguments: nonce - pointer to 128-bit nonce data.
|
|
mac - pointer to 128-bit mac data.
|
|
if NULL, it assumes the mac will be sent from
|
|
the input FIFO.
|
|
adataLength - length of the associated data.
|
|
pdataLength - length of the payload data.
|
|
it excludes mac length even if the mac will be
|
|
sent from the input FIFO.
|
|
isDistA - whether associated data will be output from the
|
|
output FIFO or not.
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCcmDecAsync(const u96 *nonce, const u128 *mac, u32 adataLength, u32 pdataLength, BOOL isDistA, AESCallback callback, void *arg)
|
|
{
|
|
OSIntrMode enabled;
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(nonce);
|
|
AES_ASSERT_DATA_LENGTH(adataLength);
|
|
AES_ASSERT_DATA_LENGTH(pdataLength);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
if (mac)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_CCM_DEC;
|
|
const u8 size = AES_PXI_SIZE_START_CCM_DEC;
|
|
u8 data[size];
|
|
|
|
// データ作成
|
|
AES_PACK_U96(&data[0], nonce);
|
|
AES_PACK_U128(&data[12], mac);
|
|
AES_PACK_U32(&data[28], &adataLength);
|
|
AES_PACK_U32(&data[32], &pdataLength);
|
|
data[36] = (u8)isDistA;
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_CCM_DEC_NOMAC;
|
|
const u8 size = AES_PXI_SIZE_START_CCM_DEC_NOMAC;
|
|
u8 data[size];
|
|
|
|
// データ作成
|
|
AES_PACK_U96(&data[0], nonce);
|
|
AES_PACK_U32(&data[12], &adataLength);
|
|
AES_PACK_U32(&data[16], &pdataLength);
|
|
data[20] = (u8)isDistA;
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCcmDec
|
|
|
|
Description: start AES engine for AES-CCM decryption.
|
|
sync version.
|
|
|
|
Arguments: nonce - pointer to 128-bit nonce data.
|
|
mac - pointer to 128-bit mac data.
|
|
if NULL, it assumes the mac will be sent from
|
|
the input FIFO.
|
|
adataLength - length of the associated data.
|
|
pdataLength - length of the payload data.
|
|
it excludes mac length even if the mac will be
|
|
sent from the input FIFO.
|
|
isDistA - whether associated data will be output from the
|
|
output FIFO or not.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCcmDec(const u96 *nonce, const u128 *mac, u32 adataLength, u32 pdataLength, BOOL isDistA)
|
|
{
|
|
aesWork.result = AES_StartCcmDecAsync(nonce, mac, adataLength, pdataLength, isDistA, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCcmEncAsync
|
|
|
|
Description: start AES engine for AES-CCM encryption.
|
|
async version.
|
|
|
|
Arguments: nonce - pointer to 128-bit nonce data.
|
|
adataLength - length of the associated data.
|
|
pdataLength - length of the payload data.
|
|
note that output length will be extended for
|
|
the mac data.
|
|
isDistA - whether associated data will be output from the
|
|
output FIFO or not.
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCcmEncAsync(const u96 *nonce, u32 adataLength, u32 pdataLength, BOOL isDistA, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_CCM_ENC;
|
|
const u8 size = AES_PXI_SIZE_START_CCM_ENC;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(nonce);
|
|
AES_ASSERT_DATA_LENGTH(adataLength);
|
|
AES_ASSERT_DATA_LENGTH(pdataLength);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U96(&data[0], nonce);
|
|
AES_PACK_U32(&data[12], &adataLength);
|
|
AES_PACK_U32(&data[16], &pdataLength);
|
|
data[20] = (u8)isDistA;
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCcmEnc
|
|
|
|
Description: start AES engine for AES-CCM encryption.
|
|
sync version.
|
|
|
|
Arguments: nonce - pointer to 128-bit nonce data.
|
|
adataLength - length of the associated data.
|
|
pdataLength - length of the payload data.
|
|
note that output length will be extended for
|
|
the mac data.
|
|
isDistA - whether associated data will be output from the
|
|
output FIFO or not.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCcmEnc(const u96 *nonce, u32 adataLength, u32 pdataLength, BOOL isDistA)
|
|
{
|
|
aesWork.result = AES_StartCcmEncAsync(nonce, adataLength, pdataLength, isDistA, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCtrDecAsync
|
|
|
|
Description: start AES engine for AES-CTR encryption/decryption.
|
|
async version.
|
|
|
|
Arguments: iv - pointer to 128-bit iv data.
|
|
length - length of the data.
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCtrDecAsync(const u128 *iv, u32 length, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_CTR;
|
|
const u8 size = AES_PXI_SIZE_START_CTR;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(iv);
|
|
AES_ASSERT_DATA_LENGTH(length);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U128(&data[0], iv);
|
|
AES_PACK_U32(&data[16], &length);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartCtrDec
|
|
|
|
Description: start AES engine for AES-CTR encryption/decryption.
|
|
sync version.
|
|
|
|
Arguments: iv - pointer to 128-bit iv data.
|
|
length - length of the data.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartCtrDec(const u128 *iv, u32 length)
|
|
{
|
|
aesWork.result = AES_StartCtrDecAsync(iv, length, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartDmaSendAsync
|
|
|
|
Description: AES DMA send by AES input FIFO timing.
|
|
Should call prior to the AES_Start*().
|
|
async version.
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
src : source address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartDmaSendAsync(u32 dmaNo, const void *src, u32 length, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_DMA_SEND;
|
|
const u8 size = AES_PXI_SIZE_START_DMA_SEND;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(src);
|
|
AES_ASSERT_DATA_LENGTH(length);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)dmaNo;
|
|
AES_PACK_U32(&data[1], &src);
|
|
AES_PACK_U32(&data[5], &length);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartDmaSend
|
|
|
|
Description: AES DMA send by AES input FIFO timing.
|
|
Should call prior to the AES_Start*().
|
|
sync version.
|
|
NOTE: never wait to done to transfer!
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
src : source address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartDmaSend(u32 dmaNo, const void *src, u32 length)
|
|
{
|
|
aesWork.result = AES_StartDmaSendAsync(dmaNo, src, length, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartDmaRecvAsync
|
|
|
|
Description: AES DMA receive by AES output FIFO timing.
|
|
Should call prior to the AES_Start*().
|
|
async version.
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
dest : destination address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartDmaRecvAsync(u32 dmaNo, const void *dest, u32 length, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_START_DMA_RECV;
|
|
const u8 size = AES_PXI_SIZE_START_DMA_RECV;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(dest);
|
|
AES_ASSERT_DATA_LENGTH(length);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
data[0] = (u8)dmaNo;
|
|
AES_PACK_U32(&data[1], &dest);
|
|
AES_PACK_U32(&data[5], &length);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_StartDmaRecv
|
|
|
|
Description: AES DMA receive by AES output FIFO timing.
|
|
Should call prior to the AES_Start*().
|
|
sync version.
|
|
NOTE: never wait to done to transfer!
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
dest : destination address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_StartDmaRecv(u32 dmaNo, const void *dest, u32 length)
|
|
{
|
|
aesWork.result = AES_StartDmaRecvAsync(dmaNo, dest, length, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitDmaAsync
|
|
|
|
Description: Waiting ARM7 side DMA is done.
|
|
It may move to MI.
|
|
async version.
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitDmaAsync(u32 dmaNo, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_WAIT_DMA;
|
|
const u8 size = AES_PXI_SIZE_WAIT_DMA;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, (u8)dmaNo) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_WaitDma
|
|
|
|
Description: Waiting ARM7 side DMA is done.
|
|
It may move to MI.
|
|
sync version.
|
|
|
|
Arguments: dmaNo : DMA channel No. (4 - 7)
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_WaitDma(u32 dmaNo)
|
|
{
|
|
aesWork.result = AES_WaitDmaAsync(dmaNo, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_CpuSendAsync
|
|
|
|
Description: send data to AES input fifo by CPU.
|
|
Should call prior to the AES_Start*().
|
|
async version.
|
|
NOTE: callback will be called after to done to transfer!
|
|
CAUTION: Cannot use AES_CPUSend*() and AES_CPURecv*() at same time.
|
|
|
|
Arguments: src : source address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_CpuSendAsync(const void *src, u32 length, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_CPU_SEND;
|
|
const u8 size = AES_PXI_SIZE_CPU_SEND;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(src);
|
|
AES_ASSERT_DATA_LENGTH(length);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U32(&data[0], &src);
|
|
AES_PACK_U32(&data[4], &length);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_CpuSend
|
|
|
|
Description: send data to AES input fifo by CPU.
|
|
Should call prior to the AES_Start*().
|
|
sync version.
|
|
CAUTION: Cannot use AES_CPUSend*() and AES_CPURecv*() at same time.
|
|
|
|
Arguments: src : source address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_CpuSend(const void *src, u32 length)
|
|
{
|
|
aesWork.result = AES_CpuSendAsync(src, length, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_CpuRecvAsync
|
|
|
|
Description: receive data from AES input fifo by CPU.
|
|
Should call prior to the AES_Start*().
|
|
async version.
|
|
NOTE: callback will be called after to done to transfer!
|
|
CAUTION: Cannot use AES_CPUSend*() and AES_CPURecv*() at same time.
|
|
|
|
Arguments: dest : destination address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_CpuRecvAsync(const void *dest, u32 length, AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_CPU_RECV;
|
|
const u8 size = AES_PXI_SIZE_CPU_RECV;
|
|
OSIntrMode enabled;
|
|
u8 data[size];
|
|
int i;
|
|
|
|
SDK_NULL_ASSERT(dest);
|
|
AES_ASSERT_DATA_LENGTH(length);
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
// データ作成
|
|
AES_PACK_U32(&data[0], &dest);
|
|
AES_PACK_U32(&data[4], &length);
|
|
|
|
// コマンド送信
|
|
if (AesSendPxiCommand(command, size, data[0]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
for (i = 1; i < size; i+=3) {
|
|
if (AesSendPxiData(&data[i]) == FALSE)
|
|
{
|
|
return AES_RESULT_SEND_ERROR;
|
|
}
|
|
}
|
|
|
|
return AES_RESULT_SUCCESS;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_CpuRecv
|
|
|
|
Description: receive data from AES input fifo by CPU.
|
|
Should call prior to the AES_Start*().
|
|
sync version.
|
|
CAUTION: Cannot use AES_CPUSend*() and AES_CPURecv*() at same time.
|
|
|
|
Arguments: dest : destination address
|
|
length : transfer size (byte) (multiple of 16 bytes)
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_CpuRecv(const void *dest, u32 length)
|
|
{
|
|
aesWork.result = AES_CpuRecvAsync(dest, length, AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_TryLockAsync
|
|
|
|
Description: AESライブラリをARM7から使われないように試みる。
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_TryLockAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_TRY_LOCK;
|
|
const u8 size = AES_PXI_SIZE_TRY_LOCK;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_TryLock
|
|
|
|
Description: AESライブラリをARM7から使われないように試みる。
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_TryLock(void)
|
|
{
|
|
aesWork.result = AES_TryLockAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_UnlockAsync
|
|
|
|
Description: AESライブラリのARM9側のロックを解除する
|
|
async version.
|
|
|
|
Arguments: callback - 非同期処理が完了した再に呼び出す関数を指定
|
|
arg - コールバック関数の呼び出し時の引数を指定。
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_UnlockAsync(AESCallback callback, void *arg)
|
|
{
|
|
const AESPxiCommand command = AES_PXI_COMMAND_UNLOCK;
|
|
const u8 size = AES_PXI_SIZE_UNLOCK;
|
|
OSIntrMode enabled;
|
|
|
|
SDK_NULL_ASSERT(callback);
|
|
|
|
enabled = OS_DisableInterrupts();
|
|
if (aesWork.lock)
|
|
{
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
return AES_RESULT_BUSY;
|
|
}
|
|
aesWork.lock = TRUE;
|
|
(void)OS_RestoreInterrupts(enabled);
|
|
// コールバック設定
|
|
aesWork.callback = callback;
|
|
aesWork.callbackArg = arg;
|
|
|
|
return AesSendPxiCommand(command, size, 0) ? AES_RESULT_SUCCESS : AES_RESULT_SEND_ERROR;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AES_Unlock
|
|
|
|
Description: AESライブラリをARM7から使われないように試みる。
|
|
sync version.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: AESResult
|
|
*---------------------------------------------------------------------------*/
|
|
AESResult AES_Unlock(void)
|
|
{
|
|
aesWork.result = AES_UnlockAsync(AesSyncCallback, 0);
|
|
if (aesWork.result == AES_RESULT_SUCCESS)
|
|
{
|
|
AesWaitBusy();
|
|
}
|
|
return aesWork.result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesSendPxiCommand
|
|
|
|
Description: 指定先頭コマンドをPXI経由でARM7に送信する。
|
|
|
|
Arguments: command - 対象コマンド
|
|
size - 送信データサイズ (バイト単位)
|
|
data - 先頭データ (1バイトのみ)
|
|
|
|
Returns: BOOL - PXIに対して送信が完了した場合TRUEを、
|
|
PXIによる送信に失敗した場合FALSEを返す。
|
|
*---------------------------------------------------------------------------*/
|
|
static BOOL AesSendPxiCommand(AESPxiCommand command, u8 size, u8 data)
|
|
{
|
|
u32 pxiData = (u32)(AES_PXI_START_BIT |
|
|
((command << AES_PXI_COMMAND_SHIFT) & AES_PXI_COMMAND_MASK) |
|
|
((size << AES_PXI_DATA_NUMS_SHIFT) & AES_PXI_DATA_NUMS_MASK) |
|
|
((data << AES_PXI_1ST_DATA_SHIFT) & AES_PXI_1ST_DATA_MASK));
|
|
if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_AES, pxiData, 0))
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesSendPxiData
|
|
|
|
Description: 指定後続データをPXI経由でARM7に送信する。
|
|
|
|
Arguments: pData - 3バイトデータの先頭へのポインタ
|
|
|
|
Returns: BOOL - PXIに対して送信が完了した場合TRUEを、
|
|
PXIによる送信に失敗した場合FALSEを返す。
|
|
*---------------------------------------------------------------------------*/
|
|
static BOOL AesSendPxiData(u8 *pData)
|
|
{
|
|
u32 pxiData = (u32)((pData[0] << 16) | (pData[1] << 8) | pData[2]);
|
|
if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_AES, pxiData, 0))
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesPxiCallback
|
|
|
|
Description: 非同期RTC関数用の共通コールバック関数。
|
|
|
|
Arguments: tag - PXI tag which show message type.
|
|
data - message from ARM7.
|
|
err - PXI transfer error flag.
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void AesPxiCallback(PXIFifoTag tag, u32 data, BOOL err)
|
|
{
|
|
#pragma unused( tag )
|
|
AESResult result;
|
|
AESPxiResult pxiResult;
|
|
u8 command;
|
|
|
|
// PXI通信エラーを確認
|
|
if (err)
|
|
{
|
|
// シーケンスを強制終了
|
|
AesCallCallbackAndUnlock(AES_RESULT_FATAL_ERROR);
|
|
return;
|
|
}
|
|
|
|
// 受信データを解析
|
|
SDK_ASSERT((data & (AES_PXI_START_BIT | AES_PXI_RESULT_BIT)) == (AES_PXI_START_BIT | AES_PXI_RESULT_BIT));
|
|
|
|
command = (u8)((data & AES_PXI_COMMAND_MASK) >> AES_PXI_COMMAND_SHIFT);
|
|
pxiResult = (AESPxiResult)((data & AES_PXI_1ST_DATA_MASK) >> AES_PXI_1ST_DATA_SHIFT);
|
|
|
|
// 処理結果を確認
|
|
switch (pxiResult)
|
|
{
|
|
case AES_PXI_RESULT_SUCCESS:
|
|
result = AES_RESULT_SUCCESS;
|
|
break;
|
|
case AES_PXI_RESULT_SUCCESS_TRUE:
|
|
result = AES_RESULT_SUCCESS_TRUE;
|
|
break;
|
|
case AES_PXI_RESULT_SUCCESS_FALSE:
|
|
result = AES_RESULT_SUCCESS_FALSE;
|
|
break;
|
|
case AES_PXI_RESULT_INVALID_COMMAND:
|
|
result = AES_RESULT_INVALID_COMMAND;
|
|
break;
|
|
case AES_PXI_RESULT_INVALID_PARAMETER:
|
|
result = AES_RESULT_ILLEGAL_PARAMETER;
|
|
break;
|
|
case AES_PXI_RESULT_ILLEGAL_STATUS:
|
|
result = AES_RESULT_ILLEGAL_STATUS;
|
|
break;
|
|
case AES_PXI_RESULT_BUSY:
|
|
result = AES_RESULT_BUSY;
|
|
break;
|
|
default:
|
|
result = AES_RESULT_FATAL_ERROR;
|
|
}
|
|
|
|
// コールバックの呼び出し
|
|
AesCallCallbackAndUnlock(result);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesSyncCallback
|
|
|
|
Description: 同期API用のコールバック
|
|
|
|
Arguments: result - ARM7から送られた結果
|
|
arg - 未使用
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void AesSyncCallback(AESResult result, void *arg)
|
|
{
|
|
#pragma unused(arg)
|
|
aesWork.result = result;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesCallCallbackAndUnlock
|
|
|
|
Description: コールバックの呼び出しとロックの解除を行う
|
|
|
|
Arguments: result - ARM7から送られた結果
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void AesCallCallbackAndUnlock(AESResult result)
|
|
{
|
|
AESCallback cb;
|
|
|
|
if (aesWork.lock)
|
|
{
|
|
aesWork.lock = FALSE;
|
|
}
|
|
if (aesWork.callback)
|
|
{
|
|
cb = aesWork.callback;
|
|
aesWork.callback = NULL;
|
|
cb(result, aesWork.callbackArg);
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: AesWaitBusy
|
|
|
|
Description: AESの非同期処理がロックされている間待つ。
|
|
|
|
Arguments: None.
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
#if 0
|
|
#include <nitro/code32.h>
|
|
static asm void AesWaitBusy(void)
|
|
{
|
|
ldr r12, =aesWork.lock
|
|
loop:
|
|
ldr r0, [ r12, #0 ]
|
|
cmp r0, #TRUE
|
|
beq loop
|
|
bx lr
|
|
}
|
|
#include <nitro/codereset.h>
|
|
#else
|
|
extern void PXIi_HandlerRecvFifoNotEmpty(void);
|
|
static void AesWaitBusy(void)
|
|
{
|
|
volatile BOOL *p = &aesWork.lock;
|
|
|
|
while (*p)
|
|
{
|
|
if (OS_GetCpsrIrq() == OS_INTRMODE_IRQ_DISABLE)
|
|
{
|
|
PXIi_HandlerRecvFifoNotEmpty();
|
|
}
|
|
}
|
|
}
|
|
#endif
|