1 /*---------------------------------------------------------------------------*
2 Project: NitroSDK - CRYPTO - demos
3 File: main.c
4
5 Copyright 2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date::$
14 $Rev:$
15 $Author:$
16 *---------------------------------------------------------------------------*/
17 /*---------------------------------------------------------------------------*
18 This demo confirms that the CRYPTO library's RSA electronic signature functions operate properly.
19 *---------------------------------------------------------------------------*/
20
21 #include <nitro.h>
22 #include <nitro/crypto.h>
23 #include <string.h>
24 #include "DEMO.h"
25
26 //#define PRINT_ALLOCATION
27 //#define PRINT_TIME
28
29 extern const unsigned char rsa1024_pub[], rsa1024_sec[];
30 extern const unsigned long rsa1024_pub_len, rsa1024_sec_len;
31
32 static void InitializeAllocateSystem(void);
33 static void VBlankIntr(void);
34 static void DisplayInit(void);
35 static void FillScreen(u16 col);
36 static BOOL RsaTest(void);
37 static BOOL sign_verify( char *teststr, void *pubkey, void *seckey, const unsigned long seckey_len );
38 static u32 GetStringLength(char* str);
39 static void PrintBinary(u8* ptr, int len);
40
41 /*---------------------------------------------------------------------------*
42 Variable Definitions
43 *---------------------------------------------------------------------------*/
44
45 #ifdef PRINT_ALLOCATION
46 static u32 total_allocated_size = 0;
47 #endif
48
49 static const unsigned char rsa512_pub[]={
50 0x30, 0x5C, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
51 0x00, 0x03, 0x4B, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xAA, 0x3D, 0x39, 0x23, 0x81, 0x1E, 0x04,
52 0xDB, 0x25, 0x91, 0xE4, 0x15, 0xA5, 0x3A, 0x9A, 0xCF, 0x64, 0x7F, 0x2F, 0xD6, 0x03, 0xB1, 0x6C,
53 0xA4, 0x1E, 0x6A, 0x4D, 0x7C, 0x9A, 0x02, 0x7D, 0x9A, 0x8E, 0xF9, 0x8F, 0x61, 0x9C, 0x0E, 0x42,
54 0x49, 0x58, 0xBB, 0x96, 0xB1, 0x1F, 0x7C, 0xCA, 0x7B, 0x2A, 0x75, 0x3A, 0x6C, 0x82, 0x4F, 0xF9,
55 0xF5, 0xB2, 0x11, 0xB7, 0xC4, 0xCC, 0xF9, 0x6D, 0xE7, 0x02, 0x03, 0x01, 0x00, 0x01
56 };
57 static const int rsa512_pub_len = 0x5E;
58
59 static const unsigned char rsa512_sec[]={
60 0x30, 0x82, 0x01, 0x3A, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xAA, 0x3D, 0x39, 0x23, 0x81, 0x1E,
61 0x04, 0xDB, 0x25, 0x91, 0xE4, 0x15, 0xA5, 0x3A, 0x9A, 0xCF, 0x64, 0x7F, 0x2F, 0xD6, 0x03, 0xB1,
62 0x6C, 0xA4, 0x1E, 0x6A, 0x4D, 0x7C, 0x9A, 0x02, 0x7D, 0x9A, 0x8E, 0xF9, 0x8F, 0x61, 0x9C, 0x0E,
63 0x42, 0x49, 0x58, 0xBB, 0x96, 0xB1, 0x1F, 0x7C, 0xCA, 0x7B, 0x2A, 0x75, 0x3A, 0x6C, 0x82, 0x4F,
64 0xF9, 0xF5, 0xB2, 0x11, 0xB7, 0xC4, 0xCC, 0xF9, 0x6D, 0xE7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
65 0x40, 0x75, 0x8E, 0xA1, 0x8E, 0x6A, 0xF3, 0x17, 0xD7, 0x5D, 0x32, 0x49, 0x96, 0xC8, 0xEA, 0x97,
66 0x4C, 0xEF, 0xD1, 0x04, 0x6F, 0x7D, 0x4D, 0x60, 0x00, 0x55, 0x20, 0x83, 0x31, 0xB0, 0x08, 0x58,
67 0x42, 0xEA, 0x75, 0x28, 0xB7, 0xB7, 0x44, 0xA7, 0x03, 0xF8, 0xEC, 0x80, 0x67, 0xD2, 0xF5, 0x44,
68 0x14, 0x77, 0x7D, 0x3F, 0xE7, 0x12, 0x2C, 0xAB, 0xE8, 0xBA, 0x52, 0x0E, 0xD5, 0x1F, 0xE5, 0xC1,
69 0x81, 0x02, 0x21, 0x00, 0xD1, 0xE4, 0x7B, 0xDE, 0x44, 0xE2, 0x4E, 0x03, 0xE5, 0x74, 0xCD, 0x89,
70 0xFD, 0x15, 0x8A, 0xD8, 0xAE, 0xF4, 0x67, 0x87, 0xCF, 0x65, 0x52, 0x3C, 0x23, 0x13, 0x2B, 0xE9,
71 0x97, 0x33, 0x26, 0x69, 0x02, 0x21, 0x00, 0xCF, 0xA2, 0xCA, 0xF1, 0x9F, 0xB0, 0x49, 0x1E, 0x4E,
72 0x64, 0x5F, 0xC7, 0x21, 0xE0, 0x71, 0x7E, 0x93, 0x7A, 0x5B, 0x20, 0xB1, 0x89, 0xAF, 0xF9, 0xC8,
73 0x96, 0x23, 0xBB, 0x72, 0xFC, 0x87, 0xCF, 0x02, 0x21, 0x00, 0xA8, 0xF7, 0x3C, 0x58, 0x44, 0x2F,
74 0xC2, 0x0A, 0x14, 0xEF, 0xA0, 0x7F, 0x13, 0x04, 0x02, 0x90, 0x48, 0xD7, 0x6B, 0x78, 0xC3, 0x16,
75 0x97, 0xCA, 0xDD, 0x99, 0x93, 0x62, 0x2A, 0x5B, 0xFC, 0xF1, 0x02, 0x20, 0x11, 0x44, 0x4E, 0x70,
76 0x2D, 0x81, 0x71, 0x73, 0x2D, 0xBD, 0xB7, 0x21, 0x4E, 0x35, 0xE5, 0xFA, 0x4A, 0xB5, 0x60, 0x22,
77 0xA5, 0xE0, 0xF7, 0x5B, 0x64, 0x4C, 0xE8, 0x07, 0xCC, 0x96, 0x27, 0x8D, 0x02, 0x20, 0x42, 0xEA,
78 0x98, 0x73, 0x96, 0x3E, 0xAC, 0x03, 0x3B, 0x19, 0xD0, 0xB7, 0x29, 0x11, 0x94, 0x25, 0x0E, 0x98,
79 0xC4, 0x7C, 0xA5, 0x95, 0x64, 0x02, 0x34, 0xB8, 0x4B, 0x66, 0x1E, 0x7B, 0x99, 0xB4
80 };
81 static const int rsa512_sec_len = 0x13E;
82
83
84 /*---------------------------------------------------------------------------*
85 Function definitions
86 *---------------------------------------------------------------------------*/
87
88 /*---------------------------------------------------------------------------*
89 Name: MyAlloc
90
91 Description: OS_Alloc wrapper function.
92 *---------------------------------------------------------------------------*/
MyAlloc(u32 size)93 static void* MyAlloc(u32 size)
94 {
95 void* ptr;
96 #ifdef PRINT_ALLOCATION
97 ptr = OS_Alloc(size+4);
98 *(u32*)ptr = size;
99 (u8*)ptr += 4;
100 total_allocated_size += size;
101 OS_TPrintf("Allocate %d bytes from %p: total %d bytes\n", size, ptr, total_allocated_size);
102 #else
103 ptr = OS_Alloc(size);
104 #endif
105 return ptr;
106 }
107
108 /*---------------------------------------------------------------------------*
109 Name: MyFree
110
111 Description: OS_Free wrapper function.
112 *---------------------------------------------------------------------------*/
MyFree(void * ptr)113 static void MyFree(void* ptr)
114 {
115 #ifdef PRINT_ALLOCATION
116 u32 size;
117 (u8*)ptr -= 4;
118 size = *(u32*)ptr;
119 total_allocated_size -= size;
120 OS_TPrintf("Free %d bytes from %p: total %d bytes\n", size, ptr, total_allocated_size);
121 #endif
122 OS_Free(ptr);
123 }
124
125 /*---------------------------------------------------------------------------*
126 Name: MyRealloc
127
128 Description: The realloc function.
129 *---------------------------------------------------------------------------*/
130 #ifndef MIN
131 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
132 #endif
133
MyRealloc(void * ptr,u32 new_size,u32 old_size)134 static void* MyRealloc(void* ptr, u32 new_size, u32 old_size)
135 {
136 void *buf;
137 #ifdef PRINT_ALLOCATION
138 u32 size;
139
140 buf = OS_Alloc(new_size+4);
141 *(u32*)buf = new_size;
142 (u8*)buf += 4;
143 total_allocated_size += new_size;
144 OS_TPrintf("Reallocate %d bytes from %p: total %d bytes\n", new_size, ptr, total_allocated_size);
145
146 (u8*)ptr -= 4;
147 size = *(u32*)ptr;
148 total_allocated_size -= size;
149 OS_TPrintf("Free(for realloc) %d bytes from %p: total %d bytes\n", size, ptr, total_allocated_size);
150 SDK_ASSERT(size == old_size);
151 OS_Free(ptr);
152 #else
153 if ((buf = OS_Alloc(new_size)) == NULL)
154 {
155 return NULL;
156 }
157
158 MI_CpuCopy8(ptr, buf, MIN(new_size, old_size));
159 OS_Free(ptr);
160 #endif
161
162 return buf;
163 }
164
165 /*---------------------------------------------------------------------------*
166 Name: NitroMain
167
168 Description: Initialization and main loop.
169
170 Arguments: None.
171
172 Returns: None.
173 *---------------------------------------------------------------------------*/
NitroMain(void)174 void NitroMain(void)
175 {
176 // Various types of initialization
177 OS_Init();
178 InitializeAllocateSystem();
179
180 // When in NITRO mode, stopped by Panic
181 DEMOCheckRunOnTWL();
182
183 DisplayInit();
184
185 if (RsaTest())
186 {
187 // Success
188 OS_TPrintf("------ Test Succeeded ------\n");
189 FillScreen(GX_RGB(0, 31, 0));
190 }
191 else
192 {
193 // Failed
194 OS_TPrintf("****** Test Failed ******\n");
195 FillScreen(GX_RGB(31, 0, 0));
196 }
197
198 // Main loop
199 while (TRUE)
200 {
201 // Waiting for the V-Blank
202 OS_WaitVBlankIntr();
203 }
204 }
205
206 /*---------------------------------------------------------------------------*
207 Name: VBlankIntr
208
209 Description: V-Blank interrupt vector.
210
211 Arguments: None.
212
213 Returns: None.
214 *---------------------------------------------------------------------------*/
VBlankIntr(void)215 static void VBlankIntr(void)
216 {
217 // Sets the IRQ check flag
218 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
219 }
220
221 /*---------------------------------------------------------------------------*
222 Name: InitializeAllocateSystem
223
224 Description: Initializes the memory allocation system within the main memory arena.
225
226 Arguments: None.
227
228 Returns: None.
229 *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)230 static void InitializeAllocateSystem(void)
231 {
232 void *tempLo;
233 OSHeapHandle hh;
234
235 tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
236 OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
237 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
238 if (hh < 0)
239 {
240 OS_Panic("ARM9: Fail to create heap...\n");
241 }
242 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
243 }
244
245 /*---------------------------------------------------------------------------*
246 Name: DisplayInit
247
248 Description: Graphics initialization.
249
250 Arguments: None.
251
252 Returns: None.
253 *---------------------------------------------------------------------------*/
DisplayInit(void)254 static void DisplayInit(void)
255 {
256
257 GX_Init();
258 FX_Init();
259
260 GX_DispOff();
261 GXS_DispOff();
262
263 GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
264
265 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
266 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
267 (void)GX_VBlankIntr(TRUE); // To generate V-Blank interrupt request
268 (void)OS_EnableIrq();
269
270
271 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
272 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
273
274 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // Clear OAM
275 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // Clear the standard palette
276
277 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // Clear OAM
278 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // Clear the standard palette
279 MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
280
281
282 GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB); // Set VRAM-A, B for OBJ
283
284 GX_SetGraphicsMode(GX_DISPMODE_VRAM_C, // VRAM mode
285 (GXBGMode)0, // Dummy
286 (GXBG0As)0); // Dummy
287
288 GX_SetVisiblePlane(GX_PLANEMASK_OBJ); // Make OBJ visible
289 GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K); // 2D mapping OBJ
290
291 OS_WaitVBlankIntr(); // Waiting for the end of the V-Blank interrupt
292 GX_DispOn();
293
294 }
295
296
297 /*---------------------------------------------------------------------------*
298 Name: FillScreen
299
300 Description: Fills the screen.
301
302 Arguments: col: FillColor
303
304 Returns: None.
305 *---------------------------------------------------------------------------*/
FillScreen(u16 col)306 static void FillScreen(u16 col)
307 {
308 MI_CpuFill16((void *)HW_LCDC_VRAM_C, col, 256 * 192 * 2);
309 }
310
311 /*---------------------------------------------------------------------------*
312 Name: RsaTest
313
314 Description: Test routine for the electronic signature functions.
315
316 Arguments: None.
317
318 Returns: TRUE if test succeeds.
319 *---------------------------------------------------------------------------*/
320 #define PrintResultEq( a, b, f ) \
321 { OS_TPrintf( ((a) == (b)) ? "[--OK--] " : "[**NG**] " ); (f) = (f) && ((a) == (b)); }
322
323 #define CheckAndPrintErr( result, str ) \
324 { if(OS_IsRunOnTwl() == TRUE){ \
325 if(result < 0) { OS_TPrintf( "Error: %d (%s)\n", result, str ); return FALSE;} \
326 }else{ \
327 if(result >= 0){ OS_TPrintf( "Error: %d (%s)\n", result, str ); return FALSE;} \
328 } \
329 }
330
RsaTest(void)331 static BOOL RsaTest(void)
332 {
333 BOOL flag = TRUE;
334
335 // Perform electronic signature operation test
336 {
337 char teststr[] = "Copyright 2003-2005 Nintendo. All rights reserved.";
338 BOOL ret;
339
340 CRYPTO_SetMemAllocator(MyAlloc, MyFree, MyRealloc);
341
342 /* RSA sign and verify */
343 ret = sign_verify(teststr, (void *)rsa1024_pub, (void *)rsa1024_sec, rsa1024_sec_len);
344 PrintResultEq(ret, TRUE, flag); OS_TPrintf("RSA sign test\n");
345 }
346
347
348 return flag;
349 }
350
sign_verify(char * teststr,void * pubkey,void * seckey,const unsigned long seckey_len)351 static BOOL sign_verify( char *teststr, void *pubkey,
352 void *seckey, const unsigned long seckey_len )
353 {
354 char signstr[144];
355 unsigned char *mod_ptr;
356 s32 result;
357 s32 len;
358 CRYPTORSASignContext context;
359 CRYPTORSASignInitParam signinitparam;
360 CRYPTORSASignParam signparam;
361 #ifdef PRINT_TIME
362 OSTick begin, end, term;
363 #endif
364
365 #ifdef PRINT_TIME
366 begin = OS_GetTick();
367 #endif
368
369 /* RSA sign */
370 signinitparam.key = (void*)seckey;
371 signinitparam.key_len = seckey_len;
372 result = CRYPTO_RSA_SignInit(&context, &signinitparam);
373 CheckAndPrintErr(result, "CRYPTO_RSA_SignInit");
374
375 signparam.in = teststr;
376 signparam.in_len = strlen(teststr);
377 signparam.out = signstr;
378 signparam.out_size = sizeof(signstr);
379 len = CRYPTO_RSA_Sign(&context, &signparam);
380 CheckAndPrintErr(len, "CRYPTO_RSA_Sign");
381
382 result = CRYPTO_RSA_SignTerminate(&context);
383 CheckAndPrintErr(result, "CRYPTO_RSA_SignTerminate");
384
385 #ifdef PRINT_TIME
386 end = OS_GetTick();
387 term = OS_TicksToMicroSeconds(end - begin);
388 OS_TPrintf(" RSA sign: %d.%03d ms - %d tick\n", (u32)(term/1000), (u32)(term%1000), term);
389
390 begin = OS_GetTick();
391 #endif
392
393 if(OS_IsRunOnTwl() == FALSE){
394 return TRUE;
395 }
396
397 /* SIGN verify */
398 if((mod_ptr = CRYPTO_SIGN_GetModulus(pubkey)) == NULL)
399 {
400 OS_TPrintf( "Error: pubkey modulus find error . (CRYPTO_SIGN_GetModulus)\n" );
401 return FALSE;
402 }
403 if(CRYPTO_VerifySignature(teststr, (int)strlen(teststr), signstr, mod_ptr) == FALSE)
404 {
405 OS_TPrintf( "Error: SIGN verify error . (CRYPTO_VerifySignature)\n" );
406 return FALSE;
407 }
408
409 #ifdef PRINT_TIME
410 end = OS_GetTick();
411 term = OS_TicksToMicroSeconds(end - begin);
412 OS_TPrintf(" SIGN verify: %d.%03d ms - %d tick\n", (u32)(term/1000), (u32)(term%1000), term);
413 #endif
414
415 return TRUE;
416 }
417
418
419 /*---------------------------------------------------------------------------*
420 Name: GetStringLength
421
422 Description: Gets the length of a string.
423
424 Arguments: str: Pointer to a string
425
426 Returns: Length of string
427 *---------------------------------------------------------------------------*/
GetStringLength(char * str)428 static u32 GetStringLength(char* str)
429 {
430 u32 i;
431 for (i = 0; ; i++)
432 {
433 if (*(str++) == '\0')
434 {
435 return i;
436 }
437 }
438 }
439
440 /*---------------------------------------------------------------------------*
441 Name: PrintBinary
442
443 Description: binary string output
444
445 Arguments: ptr: Memory location to output
446 len: Length to output
447
448 Returns: None.
449 *---------------------------------------------------------------------------*/
PrintBinary(u8 * ptr,int len)450 static void PrintBinary(u8* ptr, int len)
451 {
452 #ifndef SDK_FINALROM
453 int i;
454 for (i = 0; i < len; i++)
455 {
456 if (i != 0)
457 {
458 OS_PutString(":");
459 }
460 OS_TPrintf("%02x", ptr[i]);
461 }
462 #else
463 #pragma unused(ptr,len)
464 #endif
465 return;
466 }
467
468 /*---------------------------------------------------------------------------*
469 End of file
470 *---------------------------------------------------------------------------*/
471