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