/*---------------------------------------------------------------------------* Project: NitroSDK - OS - demos - svc-sha1 File: main.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: main.c,v $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include static const u8 gs_key[128] = { 0xdc, 0x65, 0xfb, 0x36, 0xd4, 0xb4, 0x4a, 0x7a, 0x19, 0xa0, 0x61, 0x7b, 0xe7, 0x7e, 0xd6, 0x3e, 0x2d, 0xd6, 0x23, 0x86, 0x19, 0x16, 0xdd, 0xf8, 0x88, 0x53, 0x5c, 0xe2, 0x77, 0x9b, 0x8d, 0xc4, 0xe0, 0x52, 0x33, 0x9a, 0x96, 0x0b, 0xc1, 0x71, 0x85, 0x69, 0x00, 0x9d, 0x42, 0x82, 0x39, 0x6f, 0x44, 0xd0, 0xc0, 0x5e, 0x8e, 0xdf, 0xbb, 0x3f, 0xd5, 0xb7, 0x23, 0x88, 0x72, 0xe0, 0x70, 0xbc, 0x36, 0x37, 0x98, 0xfb, 0x26, 0x32, 0xcf, 0x8b, 0xb7, 0x47, 0x2c, 0x2a, 0x8b, 0xe1, 0xd0, 0xdd, 0x22, 0xfc, 0x5a, 0xca, 0x11, 0x31, 0xd0, 0x43, 0xcb, 0x25, 0xcb, 0x21, 0xb5, 0x4e, 0xa9, 0x95, 0x13, 0x22, 0x39, 0x16, 0x21, 0x9c, 0x09, 0x5d, 0xc3, 0xbf, 0x4d, 0x26, 0x45, 0x86, 0x28, 0x4e, 0x4e, 0x25, 0xc6, 0xd6, 0xc4, 0x21, 0xc0, 0x59, 0x9d, 0x05, 0x73, 0x73, 0xab, 0x2c, 0xd2, 0x2d }; static const u8 gs_sign[128] = { 0x7b, 0x11, 0x11, 0x53, 0xf9, 0xdc, 0x97, 0x59, 0x65, 0xd2, 0xa1, 0x20, 0x63, 0x55, 0x56, 0x88, 0x47, 0xe3, 0xe1, 0xae, 0x6f, 0xac, 0x66, 0xa3, 0x2f, 0x72, 0x53, 0xc5, 0xaa, 0x49, 0xd8, 0x92, 0xc6, 0xc7, 0xbe, 0xee, 0x4c, 0x69, 0x6a, 0x97, 0xf8, 0x8e, 0x4b, 0x6e, 0x7d, 0x7c, 0x43, 0xee, 0xba, 0xd8, 0x3a, 0x4b, 0xbf, 0x4a, 0xd2, 0x1a, 0x73, 0xdc, 0x84, 0x14, 0x9a, 0x29, 0xce, 0xd4, 0xdf, 0xc5, 0x2b, 0x2f, 0xa8, 0xe1, 0xd9, 0x5e, 0xd2, 0x16, 0x28, 0xdd, 0x1b, 0x49, 0x45, 0xcf, 0x60, 0xce, 0x6c, 0x5f, 0x8d, 0x33, 0x18, 0xbe, 0x46, 0xf1, 0x4c, 0xbc, 0xe1, 0x8e, 0x58, 0x96, 0x3b, 0x53, 0x05, 0xa9, 0xee, 0x33, 0x52, 0xdb, 0xe8, 0xbc, 0x41, 0xa8, 0x49, 0xf2, 0xd9, 0x77, 0x8a, 0x68, 0xb9, 0xb0, 0x33, 0x40, 0xcf, 0xad, 0x1c, 0xf1, 0x28, 0x5f, 0xba, 0xdb, 0x38, 0x7b }; static const u32 gs_data[] ATTRIBUTE_ALIGN(32) = { 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef, 0x01234567 }; static u8 gs_heap[4096] ATTRIBUTE_ALIGN(32); //================================================================================ static void dump(const char *str, const void *ptr, u32 length) { u8 *data = (u8*)ptr; int i; OS_TPrintf("\n[%s] (%d bytes):\n\t", str, length); for (i = 0; i < length; i++) { OS_TPrintf("%02X", *data++); if ((i & 0xF) == 0xF) OS_TPrintf("\n\t"); else OS_TPrintf(" "); } OS_TPrintf("\n"); } /*---------------------------------------------------------------------------* Name: TwlMain Description: main Arguments: None Returns: None *---------------------------------------------------------------------------*/ void TwlMain() { SVCSignHeapContext ctx; // heap管理情報 u8 md[20]; // calculated by gs_data u8 data[128]; // decrypted by gs_sign u8 hash[20]; // decrypted and extructed by gs_sign OS_Init(); OS_Printf("ARM9 starts.\n"); OS_InitTick(); OS_EnableIrq(); dump("Source:", gs_data, sizeof(gs_data)); /* STEP0: RSA計算用ヒープを設定する */ { OSTick begin = OS_GetTick(); SVC_InitSignHeap(&ctx, gs_heap, sizeof(gs_heap)); OS_TPrintf("SVC_InitSignHeap was consumed %d usec\n", (int)OS_TicksToMicroSeconds(OS_GetTick()-begin)); } /* STEP1: 署名をRSA復号化する (raw level decryption API to use original format) */ { OSTick begin = OS_GetTick(); SVC_DecryptSign(&ctx, data, gs_sign, gs_key); OS_TPrintf("SVC_DecryptSign was consumed %d usec\n", (int)OS_TicksToMicroSeconds(OS_GetTick()-begin)); dump("RSA Result:", data, sizeof(data)); } /* STEP1x: 署名をSHA1のDER形式と見なしてハッシュを取り出す (useful API if using standard signature format) */ { OSTick begin = OS_GetTick(); SVC_DecryptSignDER(&ctx, hash, gs_sign, gs_key); OS_TPrintf("SVC_DecryptSignDER was consumed %d usec\n", (int)OS_TicksToMicroSeconds(OS_GetTick()-begin)); dump("Extracted hash:", hash, sizeof(hash)); } /* STEP2: ハッシュを計算する */ { OSTick begin = OS_GetTick(); SVC_CalcSHA1(md, gs_data, sizeof(gs_data)); // calc sha1 at once OS_TPrintf("SVC_CalcSHA1 was consumed %d usec\n", (int)OS_TicksToMicroSeconds(OS_GetTick()-begin)); dump("Hash Result:", md, sizeof(md)); } /* STEP3: ハッシュを比較する */ { int i; for (i = 0; i < sizeof(md); i++) { if (hash[i] != md[i]) { OS_TPrintf("Failed to check!\n"); break; } } if (i == sizeof(md)) { OS_TPrintf("Success to check!\n"); } } // done OS_TPrintf("\nARM9 ends.\n"); OS_Terminate(); }