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