1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - aes - demos - ctr
3 File: main.c
4
5 Copyright 2007-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:: 2009-09-24#$
14 $Rev: 11063 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #include <twl.h>
18 #include "DEMO.h"
19 #include <twl/aes.h>
20
21
22 /*---------------------------------------------------------------------------*
23 Internal variable declarations
24 *---------------------------------------------------------------------------*/
25
26 // Message queue used for waiting for the end of AES processing
27 #define DEMO_MESSAGE_Q_SIZE 1
28 static OSMessageQueue sMsgQ;
29 static OSMessage sMsgQBuffer[DEMO_MESSAGE_Q_SIZE];
30
31 // Sample data to encrypt
32 static const char DEMO_TEXT[] =
33 "These coded instructions, statements, and computer programs contain "
34 "proprietary information of Nintendo of America Inc. and/or Nintendo "
35 "Company Ltd., and are protected by Federal copyright law. They may "
36 "not be disclosed to third parties or copied or duplicated in any form, "
37 "in whole or in part, without the prior written consent of Nintendo.";
38
39 // Appropriate key to use for encryption
40 static const AESKey DEMO_KEY =
41 { 0xb3,0x2f,0x3a,0x91,0xe6,0x98,0xc2,0x76,
42 0x70,0x6d,0xfd,0x71,0xbc,0xdd,0xb3,0x93, };
43
44
45
46 /*---------------------------------------------------------------------------*
47 Internal function declarations
48 *---------------------------------------------------------------------------*/
49
50 static void DEMO_InitInteruptSystem(void);
51 static void DEMO_InitAllocSystem(void);
52 static void DEMO_AESCallback(AESResult result, void* arg);
53 static AESResult DEMO_WaitAes(OSMessageQueue* pQ);
54 static void DEMO_PrintBytes(const void* pvoid, u32 size);
55
56
57
58 /*---------------------------------------------------------------------------*
59 Function definitions
60 *---------------------------------------------------------------------------*/
61
62 /*---------------------------------------------------------------------------*
63 Name: SampleMain
64
65 Description: The main body of the sample.
66
67 Arguments: None.
68
69 Returns: Whether sample processing succeeded.
70 *---------------------------------------------------------------------------*/
SampleMain(void)71 static BOOL SampleMain(void)
72 {
73 BOOL bSuccess = FALSE;
74
75 AESResult aesResult;
76 AESCounter counter;
77 const char* pPlainText = DEMO_TEXT;
78 void* pEncrypted;
79 void* pDecrypted;
80 u32 srcSize;
81
82 // Initialize the message queue for waiting on AES processing
83 OS_InitMessageQueue(&sMsgQ, sMsgQBuffer, DEMO_MESSAGE_Q_SIZE);
84
85 // Allocate the buffer to store encrypted/decrypted data.
86 // Data size doesn't change with encryption/decryption.
87 srcSize = (u32)STD_GetStringLength(pPlainText) + 1;
88 pEncrypted = OS_Alloc(srcSize);
89 pDecrypted = OS_Alloc(srcSize);
90
91 if( ! SDK_IS_VALID_POINTER(pEncrypted)
92 || ! SDK_IS_VALID_POINTER(pDecrypted) )
93 {
94 OS_TPrintf("fail to OS_Alloc\n");
95 return FALSE;
96 }
97
98 // The first AES function called must be AES_Init.
99 AES_Init();
100
101 // The AES_Rand function is used to generate the initial counter value.
102 // The initial counter value can be any number, but you must avoid ever reusing values if at all possible.
103 //
104 aesResult = AES_Rand(&counter, sizeof(counter));
105 if( aesResult != AES_RESULT_SUCCESS )
106 {
107 OS_TPrintf("AES_Rand failed(%d)", aesResult);
108 goto error_exit;
109 }
110
111 // Configure the encryption key
112 aesResult = AES_SetKey(&DEMO_KEY);
113 if( aesResult != AES_RESULT_SUCCESS )
114 {
115 OS_TPrintf("AES_SetKey failed(%d)", aesResult);
116 goto error_exit;
117 }
118
119
120 // Display parameters
121 OS_TPrintf("---- parameter -----------\n");
122 OS_TPrintf("-- key\n");
123 DEMO_PrintBytes(&DEMO_KEY, sizeof(DEMO_KEY));
124 OS_TPrintf("-- counter initial value\n");
125 DEMO_PrintBytes(&counter, sizeof(counter));
126
127
128 // Encryption
129 {
130 // Performs encryption in AES CTR Mode
131 aesResult = AES_CtrEncrypt( &counter, // Initial counter value
132 pPlainText, // Data to be encrypted
133 srcSize, // Size of the data to encrypt
134 pEncrypted, // Buffer that stores encrypted data
135 DEMO_AESCallback, // Callback called at completion
136 &sMsgQ ); // Callback parameters
137 if( aesResult != AES_RESULT_SUCCESS )
138 {
139 OS_TPrintf("AES_CtrEncrypt failed(%d)", aesResult);
140 goto error_exit;
141 }
142
143 // Wait for encryption to end
144 aesResult = DEMO_WaitAes(&sMsgQ);
145 if( aesResult != AES_RESULT_SUCCESS )
146 {
147 OS_TPrintf("AES_CtrEncrypt failed(%d)", aesResult);
148 goto error_exit;
149 }
150
151
152 // Display results
153 OS_TPrintf("---- encrypt -------------\n");
154 OS_TPrintf("-- plain text (ascii)\n");
155 OS_PutString(pPlainText); // Use OS_PutString because OS_*Printf has a limit of 256 characters
156 OS_TPrintf("\n");
157
158 OS_TPrintf("-- plain text (hex)\n");
159 DEMO_PrintBytes(pPlainText, srcSize);
160
161 OS_TPrintf("-- encrypted (hex)\n");
162 DEMO_PrintBytes(pEncrypted, srcSize);
163 }
164
165 // Decryption
166 {
167 // Performs decryption in AES CTR Mode
168 aesResult = AES_CtrDecrypt( &counter, // Initial counter value (must be the same as that used during encryption)
169 pEncrypted, // Data to be decrypted
170 srcSize, // Size of the data to decrypt
171 pDecrypted, // Buffer that stores decrypted data
172 DEMO_AESCallback, // Callback called at completion
173 &sMsgQ ); // Callback parameters
174 if( aesResult != AES_RESULT_SUCCESS )
175 {
176 OS_TPrintf("AES_CtrDecrypt failed(%d)", aesResult);
177 goto error_exit;
178 }
179
180 // Wait for decryption to end
181 aesResult = DEMO_WaitAes(&sMsgQ);
182 if( aesResult != AES_RESULT_SUCCESS )
183 {
184 OS_TPrintf("AES_CtrDecrypt failed(%d)", aesResult);
185 goto error_exit;
186 }
187
188
189 // Display results
190 OS_TPrintf("---- decrypt -------------\n");
191 OS_TPrintf("-- encrypted (hex)\n");
192 DEMO_PrintBytes(pEncrypted, srcSize);
193
194 OS_TPrintf("-- decrypted (hex)\n");
195 DEMO_PrintBytes(pDecrypted, srcSize);
196
197 OS_TPrintf("-- decrypted (ascii)\n");
198 OS_PutString(pDecrypted); // Use OS_PutString because OS_*Printf has a limit of 256 characters
199 OS_TPrintf("\n");
200 }
201
202 // Confirm that data that was encrypted, then decrypted, matches original
203 if( MI_CpuComp8(pDecrypted, pPlainText, srcSize) == 0 )
204 {
205 OS_TPrintf("** pDecrypted == pPlainText\n");
206 bSuccess = TRUE;
207 }
208 else
209 {
210 OS_TPrintf("** pDecrypted != pPlainText\n");
211 }
212
213 error_exit:
214 OS_Free(pDecrypted);
215 OS_Free(pEncrypted);
216
217 return bSuccess;
218 }
219
220
221 /*---------------------------------------------------------------------------*
222 Name: TwlMain
223
224 Description: The main function.
225
226 Arguments: None.
227
228 Returns: None.
229 *---------------------------------------------------------------------------*/
TwlMain(void)230 void TwlMain(void)
231 {
232 BOOL bSampleSucceeded = FALSE;
233
234 // Initialization
235 OS_Init();
236 DEMO_InitInteruptSystem();
237 DEMO_InitAllocSystem();
238 OS_TPrintf("*** start aes demo\n");
239
240 // When in NITRO mode, stopped by Panic
241 DEMOCheckRunOnTWL();
242 // Run demo
243 bSampleSucceeded = SampleMain();
244
245 // Display demo run results
246 OS_TPrintf("*** End of demo\n");
247 OS_TPrintf("demo %s\n", (bSampleSucceeded ? "succeeded": "failed"));
248 GX_Init();
249 *(GXRgb*)HW_BG_PLTT = (GXRgb)(bSampleSucceeded ? GX_RGB(0, 31, 0): GX_RGB(31, 0, 0));
250 GX_DispOn();
251 OS_Terminate();
252 }
253
254
255 /*---------------------------------------------------------------------------*
256 Name: DEMO_AESCallback
257
258 Description: This is the callback called at AES processing completion.
259 It is of type AESCallback.
260
261 Arguments: result: AES processing result.
262 arg: Last argument passed in AES_Ctr
263
264 Returns: None.
265 *---------------------------------------------------------------------------*/
DEMO_AESCallback(AESResult result,void * arg)266 static void DEMO_AESCallback(AESResult result, void* arg)
267 {
268 OSMessageQueue* pQ = (OSMessageQueue*)arg;
269 (void)OS_SendMessage(pQ, (OSMessage)result, OS_MESSAGE_BLOCK);
270 }
271
272 /*---------------------------------------------------------------------------*
273 Name: DEMO_WaitAes
274
275 Description: Waits for AES processing completion and returns results.
276 DEMO_AESCallback must have been specified in AES_Ctr.
277
278 Arguments: pQ: Message queue passed as the last AES_Ctr argument
279
280 Returns: AES processing result.
281 *---------------------------------------------------------------------------*/
DEMO_WaitAes(OSMessageQueue * pQ)282 static AESResult DEMO_WaitAes(OSMessageQueue* pQ)
283 {
284 OSMessage msg;
285 (void)OS_ReceiveMessage(pQ, &msg, OS_MESSAGE_BLOCK);
286 return (AESResult)msg;
287 }
288
289 /*---------------------------------------------------------------------------*
290 Name: DEMO_PrintBytes
291
292 Description: Outputs the specified binary array in hexadecimal to debug output.
293
294 Arguments: pvoid: Pointer to the target binary array.
295 size: Number of bytes in the target binary array.
296
297 Returns: None.
298 *---------------------------------------------------------------------------*/
DEMO_PrintBytes(const void * pvoid,u32 size)299 static void DEMO_PrintBytes(const void* pvoid, u32 size)
300 {
301 const u8* p = (const u8*)pvoid;
302 u32 i;
303
304 for( i = 0; i < size; ++i )
305 {
306 OS_TPrintf("%02X ", p[i]);
307 if( i % 16 == 15 )
308 {
309 OS_TPrintf("\n");
310 }
311 }
312
313 if( i % 16 != 0 )
314 {
315 OS_TPrintf("\n");
316 }
317 }
318
319 /*---------------------------------------------------------------------------*
320 Name: DEMO_InitInteruptSystem
321
322 Description: Initializes interrupts.
323
324 Arguments: None.
325
326 Returns: None.
327 *---------------------------------------------------------------------------*/
DEMO_InitInteruptSystem(void)328 static void DEMO_InitInteruptSystem(void)
329 {
330 // Enable master interrupt flag
331 (void)OS_EnableIrq();
332 }
333
334 /*---------------------------------------------------------------------------*
335 Name: DEMO_InitAllocSystem
336
337 Description: Creates a heap and makes OS_Alloc usable.
338
339 Arguments: None.
340
341 Returns: None.
342 *---------------------------------------------------------------------------*/
DEMO_InitAllocSystem(void)343 static void DEMO_InitAllocSystem(void)
344 {
345 void* newArenaLo;
346 OSHeapHandle hHeap;
347
348 // Initialize the main arena's allocation system
349 newArenaLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
350 OS_SetMainArenaLo(newArenaLo);
351
352 // Create a heap in the main arena
353 hHeap = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
354 (void)OS_SetCurrentHeap(OS_ARENA_MAIN, hHeap);
355 }
356