diff --git a/build/libraries/aes/ARM7/aes_control.c b/build/libraries/aes/ARM7/aes_control.c index 9cccc6a..85aaac6 100644 --- a/build/libraries/aes/ARM7/aes_control.c +++ b/build/libraries/aes/ARM7/aes_control.c @@ -212,17 +212,26 @@ static void AesPxiCallback(PXIFifoTag tag, u32 data, BOOL err) case AES_PXI_COMMAND_WAIT_INPUT_FIFO_NOT_FULL: case AES_PXI_COMMAND_WAIT_OUTPUT_FIFO_NOT_EMPTY: case AES_PXI_COMMAND_IS_VALID: +#if 0 case AES_PXI_COMMAND_SELECT_KEY: case AES_PXI_COMMAND_SET_KEY: case AES_PXI_COMMAND_SET_ID: case AES_PXI_COMMAND_SET_SEED: case AES_PXI_COMMAND_SET_KEY2: +#else + case AES_PXI_COMMAND_SET_GENERAL_KEY: + case AES_PXI_COMMAND_SET_SYSTEM_KEY: + case AES_PXI_COMMAND_SET_GAME_KEY: + case AES_PXI_COMMAND_SET_SPECIAL_KEY: + case AES_PXI_COMMAND_SET_ALTERNATIVE_KEY: +#endif case AES_PXI_COMMAND_START_CCM_DEC: case AES_PXI_COMMAND_START_CCM_DEC_NOMAC: case AES_PXI_COMMAND_START_CCM_ENC: case AES_PXI_COMMAND_START_CTR: case AES_PXI_COMMAND_START_DMA_SEND: case AES_PXI_COMMAND_START_DMA_RECV: + case AES_PXI_COMMAND_WAIT_DMA: case AES_PXI_COMMAND_CPU_SEND: case AES_PXI_COMMAND_CPU_RECV: // スレッドを再開 @@ -304,8 +313,10 @@ static void AesThread(void *arg) OSMessage msg; BOOL result; - u128 data128a; + u128 data128; +#if 0 u128 data128b; +#endif u96 data96; u32 data32a; u32 data32b; @@ -371,7 +382,7 @@ static void AesThread(void *arg) AesReturnResult(aesWork.command, result ? AES_PXI_RESULT_SUCCESS_TRUE : AES_PXI_RESULT_SUCCESS_FALSE); // ARM9に処理の成功を通達 break; - +#if 0 case AES_PXI_COMMAND_SELECT_KEY: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SELECT_KEY); AES_SelectKey(aesWork.data[0]); @@ -380,40 +391,76 @@ static void AesThread(void *arg) case AES_PXI_COMMAND_SET_KEY: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_KEY); - AES_UNPACK_U128(&data128a, &aesWork.data[1]); - AES_SetKey(aesWork.data[0], &data128a); + AES_UNPACK_U128(&data128, &aesWork.data[1]); + AES_SetKey(aesWork.data[0], &data128); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; case AES_PXI_COMMAND_SET_ID: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_ID); - AES_UNPACK_U128(&data128a, &aesWork.data[1]); - AES_SetId(aesWork.data[0], &data128a); + AES_UNPACK_U128(&data128, &aesWork.data[1]); + AES_SetId(aesWork.data[0], &data128); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; case AES_PXI_COMMAND_SET_SEED: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_SEED); - AES_UNPACK_U128(&data128a, &aesWork.data[1]); - AES_SetSeed(aesWork.data[0], &data128a); + AES_UNPACK_U128(&data128, &aesWork.data[1]); + AES_SetSeed(aesWork.data[0], &data128); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; case AES_PXI_COMMAND_SET_KEY2: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_KEY2); - AES_UNPACK_U128(&data128a, &aesWork.data[1]); + AES_UNPACK_U128(&data128, &aesWork.data[1]); AES_UNPACK_U128(&data128b, &aesWork.data[17]); - AES_SetKey2(aesWork.data[1], &data128a, &data128b); + AES_SetKey2(aesWork.data[1], &data128, &data128b); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; +#else + case AES_PXI_COMMAND_SET_GENERAL_KEY: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_GENERAL_KEY); + AES_UNPACK_U128(&data128, &aesWork.data[0]); + AES_SetGeneralKey(&data128); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; + case AES_PXI_COMMAND_SET_SYSTEM_KEY: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_SYSTEM_KEY); + AES_UNPACK_U128(&data128, &aesWork.data[0]); + AES_SetSystemKey(&data128); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; + + case AES_PXI_COMMAND_SET_GAME_KEY: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_GAME_KEY); + AES_UNPACK_U128(&data128, &aesWork.data[0]); + AES_SetGameKey(&data128); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; + + case AES_PXI_COMMAND_SET_SPECIAL_KEY: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_SPECIAL_KEY); + AES_UNPACK_U128(&data128, &aesWork.data[0]); + AES_SetSpecialKey(&data128); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; + + case AES_PXI_COMMAND_SET_ALTERNATIVE_KEY: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_SET_ALTERNATIVE_KEY); + AES_UNPACK_U128(&data128, &aesWork.data[0]); + AESi_SetAlternativeKey(&data128); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; + +#endif case AES_PXI_COMMAND_START_CCM_DEC: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_START_CCM_DEC); AES_UNPACK_U96(&data96, &aesWork.data[0]); - AES_UNPACK_U128(&data128a, &aesWork.data[12]); + AES_UNPACK_U128(&data128, &aesWork.data[12]); AES_UNPACK_U32(&data32a, &aesWork.data[28]); AES_UNPACK_U32(&data32b, &aesWork.data[32]); - AES_StartCcmDec(&data96, &data128a, data32a, data32b, (BOOL)aesWork.data[36]); + AES_StartCcmDec(&data96, &data128, data32a, data32b, (BOOL)aesWork.data[36]); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; @@ -437,9 +484,9 @@ static void AesThread(void *arg) case AES_PXI_COMMAND_START_CTR: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_START_CTR); - AES_UNPACK_U128(&data128a, &aesWork.data[0]); + AES_UNPACK_U128(&data128, &aesWork.data[0]); AES_UNPACK_U32(&data32a, &aesWork.data[16]); - AES_StartCtrDec(&data128a, data32a); + AES_StartCtrDec(&data128, data32a); AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; @@ -459,6 +506,12 @@ static void AesThread(void *arg) AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 break; + case AES_PXI_COMMAND_WAIT_DMA: + AES_PXI_SIZE_CHECK(AES_PXI_SIZE_WAIT_DMA); + MIi_WaitExDma(aesWork.data[0]); + AesReturnResult(aesWork.command, AES_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達 + break; + case AES_PXI_COMMAND_CPU_SEND: AES_PXI_SIZE_CHECK(AES_PXI_SIZE_START_DMA_SEND); AES_UNPACK_U32(&data32a, &aesWork.data[0]); diff --git a/build/libraries/aes/ARM9/aes_api.c b/build/libraries/aes/ARM9/aes_api.c index 47cde6f..ffb4782 100644 --- a/build/libraries/aes/ARM9/aes_api.c +++ b/build/libraries/aes/ARM9/aes_api.c @@ -532,6 +532,7 @@ AESResult AES_IsValid(void) return aesWork.result; } +#if 0 /*---------------------------------------------------------------------------* Name: AES_SelectKeyAsync @@ -907,6 +908,389 @@ AESResult AES_SetKey2(u32 keyNo, const u128 *pId, const u128 *pSeed) } 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 @@ -1223,7 +1607,7 @@ AESResult AES_StartDmaSendAsync(u32 dmaNo, const void *src, u32 length, AESCallb u8 data[size]; int i; - SDK_NULL_ASSERT(iv); + SDK_NULL_ASSERT(src); AES_ASSERT_DATA_LENGTH(length); SDK_NULL_ASSERT(callback); @@ -1306,7 +1690,7 @@ AESResult AES_StartDmaRecvAsync(u32 dmaNo, const void *dest, u32 length, AESCall u8 data[size]; int i; - SDK_NULL_ASSERT(iv); + SDK_NULL_ASSERT(dest); AES_ASSERT_DATA_LENGTH(length); SDK_NULL_ASSERT(callback); @@ -1365,6 +1749,62 @@ AESResult AES_StartDmaRecv(u32 dmaNo, const void *dest, u32 length) } 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 @@ -1390,7 +1830,7 @@ AESResult AES_CpuSendAsync(const void *src, u32 length, AESCallback callback, vo u8 data[size]; int i; - SDK_NULL_ASSERT(iv); + SDK_NULL_ASSERT(src); AES_ASSERT_DATA_LENGTH(length); SDK_NULL_ASSERT(callback); @@ -1472,7 +1912,7 @@ AESResult AES_CpuRecvAsync(const void *dest, u32 length, AESCallback callback, v u8 data[size]; int i; - SDK_NULL_ASSERT(iv); + SDK_NULL_ASSERT(dest); AES_ASSERT_DATA_LENGTH(length); SDK_NULL_ASSERT(callback); diff --git a/build/tests/aes/aes-1/ARM7/src/main.c b/build/tests/aes/aes-1/ARM7/src/main.c index fa25ffd..af01926 100644 --- a/build/tests/aes/aes-1/ARM7/src/main.c +++ b/build/tests/aes/aes-1/ARM7/src/main.c @@ -31,12 +31,6 @@ static const u128 key = { 0x01234567, 0x89abcdef }; -static const u128 key2 = { - 0x00112233, - 0x44556677, - 0x8899aabb, - 0xccddeeff -}; static const u96 nonce = { 0x01234567, 0x89abcdef, @@ -297,7 +291,7 @@ void TwlMain() // 鍵を設定しておく AES_SetKey(0, &key); - AES_SetKey2(1, &key, &key2); + AES_SetSeed(1, &key); test0(); test1(); diff --git a/build/tests/aes/aes-1/ARM9/src/main.c b/build/tests/aes/aes-1/ARM9/src/main.c index 9edc8df..a560af3 100644 --- a/build/tests/aes/aes-1/ARM9/src/main.c +++ b/build/tests/aes/aes-1/ARM9/src/main.c @@ -27,12 +27,6 @@ static const u128 key = { 0x01234567, 0x89abcdef }; -static const u128 key2 = { - 0x00112233, - 0x44556677, - 0x8899aabb, - 0xccddeeff -}; static const u96 nonce = { 0x01234567, 0x89abcdef, @@ -61,8 +55,8 @@ static const u32 gs_data[] ATTRIBUTE_ALIGN(32) = { 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567 }; -static u8 dataA[sizeof(gs_data) + sizeof(u128)] ATTRIBUTE_ALIGN(32); -static u8 dataB[sizeof(gs_data) + sizeof(u128)] ATTRIBUTE_ALIGN(32); +static u8 dataA[sizeof(gs_data) + sizeof(u128) + 32] ATTRIBUTE_ALIGN(32); +static u8 dataB[sizeof(gs_data) + sizeof(u128) + 32] ATTRIBUTE_ALIGN(32); //================================================================================ static void dump(const char *str, void *ptr, u32 length) @@ -94,11 +88,11 @@ static void test0(void) OS_TPrintf("%s: Failed to call AES_Reset (%d).\n", __func__, result); } - // 鍵は0番目を使う - result = AES_SelectKey(0); + // 鍵を設定する + result = AES_SetGeneralKey(&key); if (AES_RESULT_SUCCESS != result) { - OS_TPrintf("%s: Failed to call AES_SelectKey (%d).\n", __func__, result); + OS_TPrintf("%s: Failed to call AES_SetGeneralKey (%d).\n", __func__, result); } #ifdef TEST0_USE_DMA_INPUT @@ -132,11 +126,11 @@ static void test0(void) #ifdef TEST0_USE_DMA_INPUT #ifdef TEST0_USE_DMA_OUTPUT - // AES完了待ち - result = AES_Wait(); + // AES出力DMA完了待ち + result = AES_WaitDma(OUTPUT_DMA); if (AES_RESULT_SUCCESS != result) { - OS_TPrintf("%s: Failed to call AES_Wait (%d).\n", __func__, result); + OS_TPrintf("%s: Failed to call AES_WaitDma (%d).\n", __func__, result); } #else // CPUで出力してみる @@ -240,10 +234,10 @@ static void test2(void) } // 鍵を設定する - result = AES_SelectKey(1); + result = AES_SetSpecialKey(&key); if (AES_RESULT_SUCCESS != result) { - OS_TPrintf("%s: Failed to call AES_SelectKey (%d).\n", __func__, result); + OS_TPrintf("%s: Failed to call AES_SetSpecialKey (%d).\n", __func__, result); } // 出力DMA設定 @@ -331,18 +325,6 @@ void TwlMain() } OS_TPrintf("AES_TryLock wad done.\n"); - // 鍵を設定しておく - result = AES_SetKey(0, &key); - if (AES_RESULT_SUCCESS != result) - { - OS_TPrintf("%s: Failed to call AES_SetKey (%d).\n", __func__, result); - } - result = AES_SetKey2(1, &key, &key2); - if (AES_RESULT_SUCCESS != result) - { - OS_TPrintf("%s: Failed to call AES_SetKey2 (%d).\n", __func__, result); - } - test0(); test1(); test2(); diff --git a/include/twl/aes/ARM7/instruction.h b/include/twl/aes/ARM7/instruction.h index 4ccd58b..e4d4b46 100644 --- a/include/twl/aes/ARM7/instruction.h +++ b/include/twl/aes/ARM7/instruction.h @@ -69,6 +69,21 @@ typedef enum } AESMacLength; +// make sense of the purpose +typedef enum +{ + AES_KEYSEL_GAME = 0, + AES_KEYSEL_SPECIAL = 1, + AES_KEYSEL_ALTERNATIVE = 2, + AES_KEYSEL_SYSTEM = 3, + + AES_KEYSEL_IPL = AES_KEYSEL_ALTERNATIVE, + + AES_KEYSEL_GENERAL = 0 // for key register +} +AESKeySel; + + /*---------------------------------------------------------------------------* 構造体定義 *---------------------------------------------------------------------------*/ @@ -229,6 +244,88 @@ void AES_SetSeed(u32 keyNo, const u128 *pSeed); *---------------------------------------------------------------------------*/ void AES_SetKey2(u32 keyNo, const u128 *pId, const u128 *pSeed); +// APIs for constract with ARM9 +/*---------------------------------------------------------------------------* + Name: AES_SetGeneralKey + + Description: set AES key normally + + Arguments: pKey - pointer to key data + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void AES_SetGeneralKey(const u128 *pKey) +{ + AES_SetKey(AES_KEYSEL_GENERAL, pKey); + AES_SelectKey(AES_KEYSEL_GENERAL); +} +/*---------------------------------------------------------------------------* + 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. + + Arguments: pKey - pointer to key data + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void AES_SetSystemKey(const u128 *pKey) +{ + AES_SetSeed(AES_KEYSEL_SYSTEM, pKey); + AES_SelectKey(AES_KEYSEL_SYSTEM); +} +/*---------------------------------------------------------------------------* + 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. + + Arguments: pKey - pointer to key data + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void AES_SetGameKey(const u128 *pKey) +{ + AES_SetSeed(AES_KEYSEL_GAME, pKey); + AES_SelectKey(AES_KEYSEL_GAME); +} +/*---------------------------------------------------------------------------* + 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. + + Arguments: pKey - pointer to key data + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void AES_SetSpecialKey(const u128 *pKey) +{ + AES_SetSeed(AES_KEYSEL_SPECIAL, pKey); + AES_SelectKey(AES_KEYSEL_SPECIAL); +} +/*---------------------------------------------------------------------------* + Name: AESi_SetAlternativeKey + + Description: set mangled AES key + + Arguments: pKey - pointer to key data + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void AESi_SetAlternativeKey(const u128 *pKey) +{ + AES_SetSeed(AES_KEYSEL_ALTERNATIVE, pKey); + AES_SelectKey(AES_KEYSEL_ALTERNATIVE); +} + /*---------------------------------------------------------------------------* Name: AES_StartCcmDec diff --git a/include/twl/aes/ARM9/aes.h b/include/twl/aes/ARM9/aes.h index 030abb7..d45e909 100644 --- a/include/twl/aes/ARM9/aes.h +++ b/include/twl/aes/ARM9/aes.h @@ -258,6 +258,7 @@ AESResult AES_IsValidAsync(AESCallback callback, void *arg); *---------------------------------------------------------------------------*/ AESResult AES_IsValid(void); +#if 0 /*---------------------------------------------------------------------------* Name: AES_SelectKeyAsync @@ -406,6 +407,154 @@ AESResult AES_SetKey2Async(u32 keyNo, const u128 *pId, const u128 *pSeed, AESCal *---------------------------------------------------------------------------*/ AESResult AES_SetKey2(u32 keyNo, const u128 *pId, const u128 *pSeed); +#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); + +/*---------------------------------------------------------------------------* + Name: AES_SetGeneralKey + + Description: set AES key normally + sync version. + + Arguments: pKey - pointer to key data + + Returns: AESResult + *---------------------------------------------------------------------------*/ +AESResult AES_SetGeneralKey(const u128 *pKey); + +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + +#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); + +/*---------------------------------------------------------------------------* + Name: AESi_SetAlternativeKey + + Description: set mangled AES key + sync version. + + Arguments: pKey - pointer to key data + + Returns: AESResult + *---------------------------------------------------------------------------*/ +AESResult AESi_SetAlternativeKey(const u128 *pKey); +#endif +#endif /*---------------------------------------------------------------------------* Name: AES_StartCcmDecAsync @@ -632,6 +781,34 @@ AESResult AES_StartDmaRecvAsync(u32 dmaNo, const void *dest, u32 size, AESCallba *---------------------------------------------------------------------------*/ AESResult AES_StartDmaRecv(u32 dmaNo, const void *dest, u32 size); +/*---------------------------------------------------------------------------* + 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); + +/*---------------------------------------------------------------------------* + 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); + /*---------------------------------------------------------------------------* Name: AES_CpuSendAsync diff --git a/include/twl/aes/common/fifo.h b/include/twl/aes/common/fifo.h index 362799a..826ef52 100644 --- a/include/twl/aes/common/fifo.h +++ b/include/twl/aes/common/fifo.h @@ -55,19 +55,28 @@ typedef enum AESPxiCommand AES_PXI_COMMAND_WAIT_INPUT_FIFO_NOT_FULL = 0x05, AES_PXI_COMMAND_WAIT_OUTPUT_FIFO_NOT_EMPTY = 0x06, AES_PXI_COMMAND_IS_VALID = 0x07, +#if 0 AES_PXI_COMMAND_SELECT_KEY = 0x10, AES_PXI_COMMAND_SET_KEY = 0x11, AES_PXI_COMMAND_SET_ID = 0x12, AES_PXI_COMMAND_SET_SEED = 0x13, AES_PXI_COMMAND_SET_KEY2 = 0x14, +#else + AES_PXI_COMMAND_SET_GENERAL_KEY = 0x10, + AES_PXI_COMMAND_SET_SYSTEM_KEY = 0x11, + AES_PXI_COMMAND_SET_GAME_KEY = 0x12, + AES_PXI_COMMAND_SET_SPECIAL_KEY = 0x13, + AES_PXI_COMMAND_SET_ALTERNATIVE_KEY = 0x14, +#endif AES_PXI_COMMAND_START_CCM_DEC = 0x20, AES_PXI_COMMAND_START_CCM_DEC_NOMAC = 0x21, AES_PXI_COMMAND_START_CCM_ENC = 0x22, AES_PXI_COMMAND_START_CTR = 0x23, AES_PXI_COMMAND_START_DMA_SEND = 0x30, AES_PXI_COMMAND_START_DMA_RECV = 0x31, - AES_PXI_COMMAND_CPU_SEND = 0x32, - AES_PXI_COMMAND_CPU_RECV = 0x33, + AES_PXI_COMMAND_WAIT_DMA = 0x32, + AES_PXI_COMMAND_CPU_SEND = 0x33, + AES_PXI_COMMAND_CPU_RECV = 0x34, AES_PXI_COMMAND_TRY_LOCK = 0x40, AES_PXI_COMMAND_UNLOCK = 0x41 @@ -85,17 +94,26 @@ typedef enum AESPxiSize AES_PXI_SIZE_WAIT_INPUT_FIFO_NOT_FULL = 0, AES_PXI_SIZE_WAIT_OUTPUT_FIFO_NOT_EMPTY = 0, AES_PXI_SIZE_IS_VALID = 0, +#if 0 AES_PXI_SIZE_SELECT_KEY = 1, // keyNo AES_PXI_SIZE_SET_KEY = 17, // keyNo, pKey(16) AES_PXI_SIZE_SET_ID = 17, // keyNo, pId(16) AES_PXI_SIZE_SET_SEED = 17, // keyNo, pSeed(16) AES_PXI_SIZE_SET_KEY2 = 33, // keyNo, pId(16), pSeed(16) +#else + AES_PXI_SIZE_SET_GENERAL_KEY = 16, // pKey(16) + AES_PXI_SIZE_SET_SYSTEM_KEY = 16, // pKey(16) + AES_PXI_SIZE_SET_GAME_KEY = 16, // pKey(16) + AES_PXI_SIZE_SET_SPECIAL_KEY = 16, // pKey(16) + AES_PXI_SIZE_SET_ALTERNATIVE_KEY = 16, // pKey(16) +#endif AES_PXI_SIZE_START_CCM_DEC = 37, // nonce(12), mac(16), alen(4), plen(4), isA AES_PXI_SIZE_START_CCM_DEC_NOMAC = 21, // nonce(12), alen(4), plen(4), isA AES_PXI_SIZE_START_CCM_ENC = 21, // nonce(12), alen(4), plen(4), isA AES_PXI_SIZE_START_CTR = 20, // iv(16), len(4) AES_PXI_SIZE_START_DMA_SEND = 9, // no, src(4), size(4) AES_PXI_SIZE_START_DMA_RECV = 9, // no, dest(4), size(4) + AES_PXI_SIZE_WAIT_DMA = 1, // no AES_PXI_SIZE_CPU_SEND = 8, // src(4), size(4) AES_PXI_SIZE_CPU_RECV = 8, // dest(4), size(4) diff --git a/readme-AES.txt b/readme-AES.txt index b8ba849..830bbda 100644 --- a/readme-AES.txt +++ b/readme-AES.txt @@ -45,25 +45,52 @@ ID また、アプリケーション依存とは、ROMヘッダ辺りを反映するということ。 上記の内容を反映するように、IDを設定することになる。 -0と1はブートローダーが、2と3はIPL ROMが設定する。 -(いつでも上書きできるので、IPL ROMで0と1も設定しておく) -●アプリケーション解放 +●アプリケーションが触ることのできる部分 アプリケーションには、KEY[0]、SEED[0]〜SEED[3]を使えるようにする。 場合によっては、SEED[2]とSEED[3]は解放させない(2つしかない) -●ARM9側API案 +●ARM7側初期化 -鍵の種類を、DEVICE_DEPEND、APPLICATION_DEPENDの -ビットORで設定できるようにするだけ。 +ROMコードで全レジスタの初期値を設定している。 +大半はダミーだが、ID関係の固定値はここでのみの設定となる。 -複数レジスタがあることも見せずに、値をほおり込むと -AESコアに送るところまで処理する。 +アプリケーションローダー用に、TwlFirm内にIDのgame_code依存 +部分のみを再設定するコードを用意している。 -・AES_SetNormalKey(u128 pKey) -・AES_SetSpecialKey(u128 pKey, u32 types) +アプリケーション起動後はIDを触ることは無い。 +●ARM9側API + +次のような個別のAPIを用意して見た。 + +AES_SetGeneralKey() KEY[0]に鍵を設定する +AES_SetSystemKey() SEED[3]に鍵を設定する +AES_SetGameKey() SEED[0]に鍵を設定する +AES_SetSpecialKey() SEED[1]に鍵を設定する +//AESi_SetAlternativeKey() SEED[2]に鍵を設定する (非公開) + +それぞれ引数をすぐに有効にするもので、「以前の鍵」という使い方は +できないようにしている。 + + +●ARM7側API + +個別に指定することも上記APIを使用することもできる。 +個別設定用に、次のenumを用意している。 +typedef enum +{ + AES_KEYSEL_GAME = 0, + AES_KEYSEL_SPECIAL = 1, + AES_KEYSEL_ALTERNATIVE = 2, + AES_KEYSEL_SYSTEM = 3, + + AES_KEYSEL_IPL = AES_KEYSEL_ALTERNATIVE, + + AES_KEYSEL_GENERAL = 0 // for key register +} +AESKeySel;