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