1 /*---------------------------------------------------------------------------*
2   Project:  NitroSDK - CRYPTO - demos
3   File:     main.c
4 
5   Copyright 2005-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:: 2008-10-20#$
14   $Rev: 9005 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 /*---------------------------------------------------------------------------*
18   This demo confirms that the RC4 algorithm for the CRYPT library works and measures its speed of operation.
19  *---------------------------------------------------------------------------*/
20 
21 #include <nitro.h>
22 #include <nitro/crypto.h>
23 
24 #define TEST_DATA_MAX_SIZE 256
25 
26 static void InitializeAllocateSystem(void);
27 static void VBlankIntr(void);
28 static void DisplayInit(void);
29 static void FillScreen(u16 col);
30 static BOOL RC4Test(void);
31 static BOOL CompareBinary(void* ptr1, void* ptr2, u32 n);
32 static u32 GetStringLength(char* str);
33 static void PrintBinary(u8* ptr, u32 len);
34 
35 /*---------------------------------------------------------------------------*
36     Variable Definitions
37  *---------------------------------------------------------------------------*/
38 
39 /*---------------------------------------------------------------------------*
40     Function Definitions
41  *---------------------------------------------------------------------------*/
42 
43 /*---------------------------------------------------------------------------*
44   Name:         NitroMain
45 
46   Description:  Initialization and main loop.
47 
48   Arguments:    None.
49 
50   Returns:      None.
51  *---------------------------------------------------------------------------*/
NitroMain(void)52 void NitroMain(void)
53 {
54     // Various types of initialization
55     OS_Init();
56     InitializeAllocateSystem();
57 
58     DisplayInit();
59 
60     if (RC4Test())
61     {
62         // Success
63         OS_TPrintf("------ Test Succeeded ------\n");
64         FillScreen(GX_RGB(0, 31, 0));
65     }
66     else
67     {
68         // Failed
69         OS_TPrintf("****** Test Failed ******\n");
70         FillScreen(GX_RGB(31, 0, 0));
71     }
72 
73     // Main loop
74     while (TRUE)
75     {
76         // Waiting for the V-Blank
77         OS_WaitVBlankIntr();
78     }
79 }
80 
81 /*---------------------------------------------------------------------------*
82   Name:         VBlankIntr
83 
84   Description:  V-Blank interrupt vector.
85 
86   Arguments:    None.
87 
88   Returns:      None.
89  *---------------------------------------------------------------------------*/
VBlankIntr(void)90 static void VBlankIntr(void)
91 {
92     // Sets the IRQ check flag
93     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
94 }
95 
96 /*---------------------------------------------------------------------------*
97   Name:         InitializeAllocateSystem
98 
99   Description:  Initializes the memory allocation system within the main memory arena.
100 
101   Arguments:    None.
102 
103   Returns:      None.
104  *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)105 static void InitializeAllocateSystem(void)
106 {
107     void *tempLo;
108     OSHeapHandle hh;
109 
110     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
111     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
112     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
113     if (hh < 0)
114     {
115         OS_Panic("ARM9: Fail to create heap...\n");
116     }
117     hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
118 }
119 
120 /*---------------------------------------------------------------------------*
121   Name:         DisplayInit
122 
123   Description:  Graphics initialization.
124 
125   Arguments:    None.
126 
127   Returns:      None.
128  *---------------------------------------------------------------------------*/
DisplayInit(void)129 static void DisplayInit(void)
130 {
131 
132     GX_Init();
133     FX_Init();
134 
135     GX_DispOff();
136     GXS_DispOff();
137 
138     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
139 
140     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
141     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
142     (void)GX_VBlankIntr(TRUE);         // To generate V-Blank interrupt request
143     (void)OS_EnableIrq();
144 
145 
146     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
147     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
148 
149     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);   // Clear OAM
150     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);     // Clear the standard palette
151 
152     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);     // Clear OAM
153     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);       // Clear the standard palette
154     MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
155 
156 
157     GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB);       // Set VRAM-A,B for OBJ
158 
159     GX_SetGraphicsMode(GX_DISPMODE_VRAM_C,      // VRAM mode
160                        (GXBGMode)0,    // Dummy
161                        (GXBG0As)0);    // Dummy
162 
163     GX_SetVisiblePlane(GX_PLANEMASK_OBJ);       // Make OBJs visible
164     GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K);   // 2D mapping OBJ
165 
166     OS_WaitVBlankIntr();              // Waiting for the end of the V-Blank interrupt
167     GX_DispOn();
168 
169 }
170 
171 
172 /*---------------------------------------------------------------------------*
173   Name:         FillScreen
174 
175   Description:  Fills the screen.
176 
177   Arguments:    col: FillColor
178 
179   Returns:      None.
180  *---------------------------------------------------------------------------*/
FillScreen(u16 col)181 static void FillScreen(u16 col)
182 {
183     MI_CpuFill16((void *)HW_LCDC_VRAM_C, col, 256 * 192 * 2);
184 }
185 
186 /*---------------------------------------------------------------------------*
187   Name:         RC4Test
188 
189   Description:  RC4 algorithm test routine.
190 
191   Arguments:    None.
192 
193   Returns:      TRUE if test succeeds.
194  *---------------------------------------------------------------------------*/
195 #define PrintResultEq( a, b, f ) \
196     { OS_TPrintf( ((a) == (b)) ? "[--OK--] " : "[**NG**] " ); (f) = (f) && ((a) == (b)); }
197 #define PrintResultBinaryEq( a, b, l, f ) \
198     { OS_TPrintf( (CompareBinary((a), (b), (l))) ? "[--OK--] " : "[**NG**] " ); (f) = (f) && (CompareBinary((a), (b), (l))); }
199 
RC4Test(void)200 static BOOL RC4Test(void)
201 {
202     int i;
203     BOOL flag = TRUE;
204 
205     // Perform RC4 operation test
206     {
207         char* d[] = {
208             "\x01\x23\x45\x67\x89\xab\xcd\xef",
209             "Copyright 2003-2005 Nintendo.  All rights reserved.",
210         };
211         char* key[] = {
212             "\x01\x23\x45\x67\x89\xab\xcd\xef",
213             "Nintendo DS Software Development Kit: Wi-Fi Library", // Only the first 16 bytes are used
214         };
215         u8 result_rc4[][TEST_DATA_MAX_SIZE] = {
216             {
217                 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96
218             },
219             {
220                 0xc6, 0x34, 0x75, 0x38, 0x0a, 0xea, 0x34, 0xe5, 0xda, 0x43, 0xb7, 0xb6, 0x07, 0x55, 0x24, 0xa8,
221                 0x07, 0x38, 0x96, 0x21, 0x41, 0x03, 0x8e, 0xc8, 0xbc, 0x6c, 0x0e, 0xfc, 0x2a, 0x10, 0xf0, 0xa9,
222                 0xee, 0x81, 0x05, 0x53, 0x60, 0xc7, 0xd7, 0xaf, 0x6a, 0x7a, 0x82, 0x6a, 0x05, 0x1f, 0x4a, 0x8c,
223                 0x85, 0xd4, 0xc1
224             },
225         };
226 
227         for (i = 0; i < sizeof(d) / sizeof(char*); i++)
228         {
229             CRYPTORC4Context context;
230             u8 result[TEST_DATA_MAX_SIZE];
231             u32 len;
232 
233             CRYPTO_RC4Init(&context, key[i], GetStringLength(key[i]));
234             len = GetStringLength(d[i]);
235             CRYPTO_RC4Encrypt(&context, d[i], len, result);
236             PrintResultBinaryEq(result, result_rc4[i], len, flag);
237             OS_TPrintf("CRYPTO_RC4: Test Case %d: encryption phase\n", i+1);
238 
239 //            PrintBinary(result, len);
240 //            OS_TPrintf("\n");
241 
242             CRYPTO_RC4(key[i], GetStringLength(key[i]), result, len);
243             PrintResultBinaryEq(d[i], result, len, flag);
244             OS_TPrintf("CRYPTO_RC4: Test Case %d: decryption phase\n", i+1);
245         }
246     }
247 
248     {
249         char* d[] = {
250             "\x01\x23\x45\x67\x89\xab\xcd\xef",
251             "Copyright 2003-2005 Nintendo.  All rights reserved.",
252         };
253         char* key[] = {
254             "\x01\x23\x45\x67\x89\xab\xcd\xef",
255             "Nintendo DS Software Development Kit: Wi-Fi Library", // Only the first 16 bytes are used
256         };
257         u8 result_rc4[][TEST_DATA_MAX_SIZE] = {
258             {
259                 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96
260             },
261             {
262                 0xc6, 0x34, 0x75, 0x38, 0x0a, 0xea, 0x34, 0xe5, 0xda, 0x43, 0xb7, 0xb6, 0x07, 0x55, 0x24, 0xa8,
263                 0x07, 0x38, 0x96, 0x21, 0x41, 0x03, 0x8e, 0xc8, 0xbc, 0x6c, 0x0e, 0xfc, 0x2a, 0x10, 0xf0, 0xa9,
264                 0xee, 0x81, 0x05, 0x53, 0x60, 0xc7, 0xd7, 0xaf, 0x6a, 0x7a, 0x82, 0x6a, 0x05, 0x1f, 0x4a, 0x8c,
265                 0x85, 0xd4, 0xc1
266             },
267         };
268 
269         for (i = 0; i < sizeof(d) / sizeof(char*); i++)
270         {
271             CRYPTORC4FastContext context;
272             u8 result[TEST_DATA_MAX_SIZE];
273             u32 len;
274 
275             CRYPTO_RC4FastInit(&context, key[i], GetStringLength(key[i]));
276             len = GetStringLength(d[i]);
277             CRYPTO_RC4FastEncrypt(&context, d[i], len, result);
278             PrintResultBinaryEq(result, result_rc4[i], len, flag);
279             OS_TPrintf("CRYPTO_RC4Fast: Test Case %d: encryption phase\n", i+1);
280 
281 //            PrintBinary(result, len);
282 //            OS_TPrintf("\n");
283 
284             CRYPTO_RC4Fast(key[i], GetStringLength(key[i]), result, len);
285             PrintResultBinaryEq(d[i], result, len, flag);
286             OS_TPrintf("CRYPTO_RC4Fast: Test Case %d: decryption phase\n", i+1);
287         }
288     }
289 
290 
291 
292 
293 
294     return flag;
295 }
296 
297 
298 /*---------------------------------------------------------------------------*
299   Name:         CompareBinary
300 
301   Description:  Compare memory contents.
302 
303   Arguments:    ptr1, ptr2: Memory locations to compare.
304                 n: Length to compare
305 
306   Returns:      If they match, TRUE.
307  *---------------------------------------------------------------------------*/
CompareBinary(void * ptr1,void * ptr2,u32 n)308 static BOOL CompareBinary(void* ptr1, void* ptr2, u32 n)
309 {
310     u32 i;
311     u8* p1 = (u8*)ptr1;
312     u8* p2 = (u8*)ptr2;
313 
314     for (i = 0; i < n; i++)
315     {
316         if (*(p1++) != *(p2++))
317         {
318             return FALSE;
319         }
320     }
321     return TRUE;
322 }
323 
324 /*---------------------------------------------------------------------------*
325   Name:         GetStringLength
326 
327   Description:  Gets the length of a string.
328 
329   Arguments:    str: Pointer to a string
330 
331   Returns:      Length of string
332  *---------------------------------------------------------------------------*/
GetStringLength(char * str)333 static u32 GetStringLength(char* str)
334 {
335     u32 i;
336     for (i = 0; ; i++)
337     {
338         if (*(str++) == '\0')
339         {
340             return i;
341         }
342     }
343 }
344 
345 /*---------------------------------------------------------------------------*
346   Name:         PrintBinary
347 
348   Description:  Binary string output.
349 
350   Arguments:    ptr: Memory location to be output
351                 len: Output length
352 
353   Returns:      None.
354  *---------------------------------------------------------------------------*/
PrintBinary(u8 * ptr,u32 len)355 static void PrintBinary(u8* ptr, u32 len)
356 {
357 #ifndef SDK_FINALROM
358     u32 i;
359     for (i = 0; i < len; i++)
360     {
361         if (i != 0)
362         {
363             OS_PutString(", ");
364         }
365         OS_TPrintf("0x%02x", ptr[i]);
366     }
367 #else
368 #pragma unused(ptr,len)
369 #endif
370     return;
371 }
372 
373 /*---------------------------------------------------------------------------*
374   End of file
375  *---------------------------------------------------------------------------*/
376