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