1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - aes - demos - encrypt
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 const char* pPlainText = DEMO_TEXT;
77 void* pEncrypted;
78 void* pDecrypted;
79 u32 plainSize;
80 u32 cipherSize;
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 // The encrypted data will increase in size by exactly the amount of AES_ENCRYPT_HEADER_SIZE.
87 plainSize = (u32)STD_GetStringLength(pPlainText) + 1;
88 cipherSize = plainSize + AES_ENCRYPT_HEADER_SIZE;
89 pEncrypted = OS_Alloc(cipherSize);
90 pDecrypted = OS_Alloc(plainSize);
91
92 if( ! SDK_IS_VALID_POINTER(pEncrypted)
93 || ! SDK_IS_VALID_POINTER(pDecrypted) )
94 {
95 OS_TPrintf("fail to OS_Alloc\n");
96 return FALSE;
97 }
98
99 // The first AES function called must be AES_Init.
100 AES_Init();
101
102 // Configure the encryption key
103 aesResult = AES_SetKey(&DEMO_KEY);
104 if( aesResult != AES_RESULT_SUCCESS )
105 {
106 OS_TPrintf("AES_SetKey failed(%d)\n", aesResult);
107 goto error_exit;
108 }
109
110
111 // Display parameters
112 OS_TPrintf("---- parameter -----------\n");
113 OS_TPrintf("-- key\n");
114 DEMO_PrintBytes(&DEMO_KEY, sizeof(DEMO_KEY));
115
116
117 // Encryption
118 {
119 // Performs encryption in AES CTR Mode
120 aesResult = AES_Encrypt( pPlainText, // Data to be encrypted
121 plainSize, // Size of the data to encrypt
122 pEncrypted, // Buffer that stores encrypted data
123 DEMO_AESCallback, // Callback called at completion
124 &sMsgQ ); // Callback parameters
125 if( aesResult != AES_RESULT_SUCCESS )
126 {
127 OS_TPrintf("AES_Encrypt failed(%d)\n", aesResult);
128 goto error_exit;
129 }
130
131 // Wait for encryption to end
132 aesResult = DEMO_WaitAes(&sMsgQ);
133 if( aesResult != AES_RESULT_SUCCESS )
134 {
135 OS_TPrintf("AES_Encrypt failed(%d)\n", aesResult);
136 goto error_exit;
137 }
138
139
140 // Display results
141 OS_TPrintf("---- encrypt -------------\n");
142 OS_TPrintf("-- plain text (ascii)\n");
143 OS_PutString(pPlainText); // Use OS_PutString because OS_*Printf has a limit of 256 characters
144 OS_TPrintf("\n");
145
146 OS_TPrintf("-- plain text (hex)\n");
147 DEMO_PrintBytes(pPlainText, plainSize);
148
149 OS_TPrintf("-- encrypted (hex)\n");
150 DEMO_PrintBytes(pEncrypted, cipherSize);
151 }
152
153 // Decryption
154 {
155 // Performs decryption in AES CTR Mode
156 aesResult = AES_Decrypt( pEncrypted, // Data to be decrypted
157 cipherSize, // Size of the data to decrypt
158 pDecrypted, // Buffer that stores decrypted data
159 DEMO_AESCallback, // Callback called at completion
160 &sMsgQ ); // Callback parameters
161 if( aesResult != AES_RESULT_SUCCESS )
162 {
163 OS_TPrintf("AES_Decrypt failed(%d)\n", aesResult);
164 goto error_exit;
165 }
166
167 // Wait for decryption to end
168 aesResult = DEMO_WaitAes(&sMsgQ);
169 if( aesResult != AES_RESULT_SUCCESS )
170 {
171 OS_TPrintf("AES_Decrypt failed(%d)\n", aesResult);
172 goto error_exit;
173 }
174
175
176 // Display results
177 OS_TPrintf("---- decrypt -------------\n");
178 OS_TPrintf("-- encrypted (hex)\n");
179 DEMO_PrintBytes(pEncrypted, cipherSize);
180
181 OS_TPrintf("-- decrypted (hex)\n");
182 DEMO_PrintBytes(pDecrypted, plainSize);
183
184 OS_TPrintf("-- decrypted (ascii)\n");
185 OS_PutString(pDecrypted); // Use OS_PutString because OS_*Printf has a limit of 256 characters
186 OS_TPrintf("\n");
187 }
188
189 // Confirm that data that was encrypted, then decrypted, matches original
190 if( MI_CpuComp8(pDecrypted, pPlainText, plainSize) == 0 )
191 {
192 OS_TPrintf("** pDecrypted == pPlainText\n");
193 bSuccess = TRUE;
194 }
195 else
196 {
197 OS_TPrintf("** pDecrypted != pPlainText\n");
198 }
199
200 error_exit:
201 OS_Free(pDecrypted);
202 OS_Free(pEncrypted);
203
204 return bSuccess;
205 }
206
207
208 /*---------------------------------------------------------------------------*
209 Name: TwlMain
210
211 Description: The main function.
212
213 Arguments: None.
214
215 Returns: None.
216 *---------------------------------------------------------------------------*/
TwlMain(void)217 void TwlMain(void)
218 {
219 BOOL bSampleSucceeded = FALSE;
220
221 // Initialization
222 OS_Init();
223 DEMO_InitInteruptSystem();
224 DEMO_InitAllocSystem();
225 OS_TPrintf("*** start aes demo\n");
226
227 // When in NITRO mode, stopped by Panic
228 DEMOCheckRunOnTWL();
229 // Run demo
230 bSampleSucceeded = SampleMain();
231
232 // Display demo run results
233 OS_TPrintf("*** End of demo\n");
234 OS_TPrintf("demo %s\n", (bSampleSucceeded ? "succeeded": "failed"));
235 GX_Init();
236 *(GXRgb*)HW_BG_PLTT = (GXRgb)(bSampleSucceeded ? GX_RGB(0, 31, 0): GX_RGB(31, 0, 0));
237 GX_DispOn();
238 OS_Terminate();
239 }
240
241
242 /*---------------------------------------------------------------------------*
243 Name: DEMO_AESCallback
244
245 Description: This is the callback called at AES processing completion.
246 It is of type AESCallback.
247
248 Arguments: result: AES processing result.
249 arg: Last argument passed in AES_Ctr
250
251 Returns: None.
252 *---------------------------------------------------------------------------*/
DEMO_AESCallback(AESResult result,void * arg)253 static void DEMO_AESCallback(AESResult result, void* arg)
254 {
255 OSMessageQueue* pQ = (OSMessageQueue*)arg;
256 (void)OS_SendMessage(pQ, (OSMessage)result, OS_MESSAGE_BLOCK);
257 }
258
259 /*---------------------------------------------------------------------------*
260 Name: DEMO_WaitAes
261
262 Description: Waits for AES processing completion and returns results.
263 DEMO_AESCallback must have been specified in AES_Ctr.
264
265 Arguments: pQ: Message queue passed as the last AES_Ctr argument
266
267 Returns: AES processing result.
268 *---------------------------------------------------------------------------*/
DEMO_WaitAes(OSMessageQueue * pQ)269 static AESResult DEMO_WaitAes(OSMessageQueue* pQ)
270 {
271 OSMessage msg;
272 (void)OS_ReceiveMessage(pQ, &msg, OS_MESSAGE_BLOCK);
273 return (AESResult)msg;
274 }
275
276 /*---------------------------------------------------------------------------*
277 Name: DEMO_PrintBytes
278
279 Description: Outputs the specified binary array in hexadecimal to debug output.
280
281 Arguments: pvoid: Pointer to the target binary array.
282 size: Number of bytes in the target binary array.
283
284 Returns: None.
285 *---------------------------------------------------------------------------*/
DEMO_PrintBytes(const void * pvoid,u32 size)286 static void DEMO_PrintBytes(const void* pvoid, u32 size)
287 {
288 const u8* p = (const u8*)pvoid;
289 u32 i;
290
291 for( i = 0; i < size; ++i )
292 {
293 OS_TPrintf("%02X ", p[i]);
294 if( i % 16 == 15 )
295 {
296 OS_TPrintf("\n");
297 }
298 }
299
300 if( i % 16 != 0 )
301 {
302 OS_TPrintf("\n");
303 }
304 }
305
306 /*---------------------------------------------------------------------------*
307 Name: DEMO_InitInteruptSystem
308
309 Description: Initializes interrupts.
310
311 Arguments: None.
312
313 Returns: None.
314 *---------------------------------------------------------------------------*/
DEMO_InitInteruptSystem(void)315 static void DEMO_InitInteruptSystem(void)
316 {
317 // Enable master interrupt flag
318 (void)OS_EnableIrq();
319 }
320
321 /*---------------------------------------------------------------------------*
322 Name: DEMO_InitAllocSystem
323
324 Description: Creates a heap and makes OS_Alloc usable.
325
326 Arguments: None.
327
328 Returns: None.
329 *---------------------------------------------------------------------------*/
DEMO_InitAllocSystem(void)330 static void DEMO_InitAllocSystem(void)
331 {
332 void* newArenaLo;
333 OSHeapHandle hHeap;
334
335 // Initialize the main arena's allocation system
336 newArenaLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
337 OS_SetMainArenaLo(newArenaLo);
338
339 // Create a heap in the main arena
340 hHeap = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
341 (void)OS_SetCurrentHeap(OS_ARENA_MAIN, hHeap);
342 }
343