blob: 1ba755e42950c1d2f197c45aa213033033ade71a [file] [log] [blame]
Dees_Troy83bd4832013-05-04 12:39:56 +00001/*
2 * ---------------------------------------------------------------------------
3 * OpenAES License
4 * ---------------------------------------------------------------------------
5 * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 * ---------------------------------------------------------------------------
29 */
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#define OAES_DEBUG 1
36#include "oaes_lib.h"
37
38static int _is_step = 1;
39
40static int step_cb(
41 const uint8_t state[OAES_BLOCK_SIZE],
42 const char * step_name,
43 int step_count,
44 void * user_data )
45{
46 size_t _buf_len;
47 char * _buf;
48
49
50 if( NULL == state )
51 return 1;
52
53 oaes_sprintf( NULL, &_buf_len, state, OAES_BLOCK_SIZE );
54 _buf = (char *) calloc( _buf_len, sizeof( char ) );
55
56 if( _buf )
57 {
58 oaes_sprintf( _buf, &_buf_len, state, OAES_BLOCK_SIZE );
59 printf( "round[%2d].%-7s --> %s", step_count, step_name, _buf );
60 free( _buf );
61 }
62
63 if( 1 == _is_step && '\n' != getchar( ) )
64 _is_step = 0;
65
66 return 0;
67}
68
69static int to_binary(uint8_t * buf, size_t * buf_len, const char * data)
70{
71 size_t _i, _buf_len_in;
72
73 if( NULL == buf_len )
74 return 1;
75
76 if( NULL == data )
77 return 1;
78
79 _buf_len_in = *buf_len;
80 *buf_len = strlen( data ) / 2;
81
82 if( NULL == buf )
83 return 0;
84
85 if( *buf_len > _buf_len_in )
86 return 1;
87
88 memset( buf, 0, strlen( data ) / 2 );
89
90 // lookup ascii table
91 for( _i = 0; _i < strlen( data ); _i++ )
92 {
93 // 0-9
94 if( data[_i] >= 0x30 && data[_i] <= 0x39 )
95 buf[_i / 2] += ( data[_i] - 0x30 ) << ( 4 * ( ( _i + 1 ) % 2 ) ) ;
96 // a-f
97 else if( data[_i] >= 0x41 && data[_i] <= 0x46 )
98 buf[_i / 2] += ( data[_i] - 0x37 ) << ( 4 * ( ( _i + 1 ) % 2 ) );
99 // A-F
100 else if( data[_i] >= 0x61 && data[_i] <= 0x66 )
101 buf[_i / 2] += ( data[_i] - 0x57 ) << ( 4 * ( ( _i + 1 ) % 2 ) );
102 // invalid character
103 else
104 return 1;
105 }
106
107 return 0;
108}
109
110static void usage(const char * exe_name)
111{
112 if( NULL == exe_name )
113 return;
114
115 printf(
116 "Usage:\n"
117 " %s [-step] [-ecb] [[-key < 128 | 192 | 256 | key_data >] [-bin] <text>\n",
118 exe_name
119 );
120}
121
122int main(int argc, char** argv)
123{
124 size_t _i;
125 OAES_CTX * ctx = NULL;
126 uint8_t *_encbuf, *_decbuf, *_key_data = NULL, *_bin_data = NULL;
127 size_t _encbuf_len, _decbuf_len, _buf_len;
128 size_t _key_data_len = 0, _bin_data_len = 0;
129 char *_buf;
130 short _is_ecb = 0, _is_bin = 0;
131 char * _text = NULL, * _key_text = NULL;
132 int _key_len = 128;
133
134 if( argc < 2 )
135 {
136 usage( argv[0] );
137 return EXIT_FAILURE;
138 }
139
140 for( _i = 1; _i < argc; _i++ )
141 {
142 int _found = 0;
143
144 if( 0 == strcmp( argv[_i], "-nostep" ) )
145 {
146 _found = 1;
147 _is_step = 0;
148 }
149
150 if( 0 == strcmp( argv[_i], "-ecb" ) )
151 {
152 _found = 1;
153 _is_ecb = 1;
154 }
155
156 if( 0 == strcmp( argv[_i], "-bin" ) )
157 {
158 _found = 1;
159 _is_bin = 1;
160 }
161
162 if( 0 == strcmp( argv[_i], "-key" ) )
163 {
164 _found = 1;
165 _i++; // len
166 if( _i >= argc )
167 {
168 printf("Error: No value specified for '-%s'.\n",
169 "key");
170 usage( argv[0] );
171 return EXIT_FAILURE;
172 }
173 _key_len = atoi( argv[_i] );
174 switch( _key_len )
175 {
176 case 128:
177 case 192:
178 case 256:
179 break;
180 default:
181 _key_text = argv[_i];
182 if( to_binary( NULL, &_key_data_len, _key_text ) )
183 {
184 printf( "Error: Invalid value [%s] specified for '-%s'.\n",
185 argv[_i], "key" );
186 return EXIT_FAILURE;
187 }
188 switch( _key_data_len )
189 {
190 case 16:
191 case 24:
192 case 32:
193 break;
194 default:
195 printf("Error: key_data [%s] specified for '-%s' has an invalid "
196 "size.\n", argv[_i], "key");
197 usage( argv[0] );
198 return EXIT_FAILURE;
199 }
200 }
201 }
202
203 if( 0 == _found )
204 {
205 if( _text )
206 {
207 printf("Error: Invalid option '%s'.\n", argv[_i]);
208 usage( argv[0] );
209 return EXIT_FAILURE;
210 }
211 else
212 {
213 _text = argv[_i];
214 if( _is_bin && to_binary( NULL, &_bin_data_len, _text ) )
215 {
216 printf( "Error: Invalid value [%s] specified for '-%s'.\n",
217 argv[_i], "bin" );
218 return EXIT_FAILURE;
219 }
220 }
221 }
222 }
223
224 if( NULL == _text )
225 {
226 usage( argv[0] );
227 return EXIT_FAILURE;
228 }
229
230 if( _is_step )
231 printf( "\nEnabling step mode, press Return to step.\n\n" );
232
233 if( _is_bin )
234 {
235 _bin_data = (uint8_t *) calloc(_bin_data_len, sizeof(uint8_t));
236 if( NULL == _bin_data )
237 {
238 printf( "Error: Failed to allocate memory.\n" );
239 return EXIT_FAILURE;
240 }
241 if( to_binary( _bin_data, &_bin_data_len, _text ) )
242 {
243 printf( "Error: Could not load data [%s].\n", _text);
244 free( _bin_data );
245 return EXIT_FAILURE;
246 }
247 }
248 else
249 {
250 oaes_sprintf( NULL, &_buf_len, (const uint8_t *)_text, strlen(_text));
251 _buf = (char *) calloc(_buf_len, sizeof(char));
252 printf( "\n***** plaintext *****\n" );
253 if( _buf )
254 {
255 oaes_sprintf( _buf, &_buf_len,
256 (const uint8_t *)_text, strlen( _text ) );
257 printf( "%s", _buf );
258 }
259 printf( "\n**********************\n" );
260 free( _buf );
261 }
262
263 ctx = oaes_alloc();
264 if( NULL == ctx )
265 {
266 printf("Error: Failed to initialize OAES.\n");
267 if( _bin_data )
268 free( _bin_data );
269 return EXIT_FAILURE;
270 }
271 if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_STEP_ON, step_cb ) )
272 printf("Error: Failed to set OAES options.\n");
273 if( _is_ecb )
274 if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) )
275 printf("Error: Failed to set OAES options.\n");
276
277 if( _key_text )
278 {
279 _key_data = (uint8_t *) calloc(_key_data_len, sizeof(uint8_t));
280 if( NULL == _key_data )
281 {
282 printf( "Error: Failed to allocate memory.\n" );
283 if( _bin_data )
284 free( _bin_data );
285 return EXIT_FAILURE;
286 }
287 if( to_binary( _key_data, &_key_data_len, _key_text ) )
288 {
289 printf( "Error: Could not load key [%s].\n", _key_text);
290 free( _key_data );
291 return EXIT_FAILURE;
292 }
293 oaes_key_import_data( ctx, _key_data, _key_data_len );
294 }
295 else
296 switch( _key_len )
297 {
298 case 128:
299 if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) )
300 printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
301 break;
302 case 192:
303 if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) )
304 printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
305 break;
306 case 256:
307 if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) )
308 printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
309 break;
310 default:
311 break;
312 }
313
314 if( _bin_data )
315 {
316 if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
317 _bin_data, _bin_data_len, NULL, &_encbuf_len ) )
318 printf("Error: Failed to retrieve required buffer size for encryption.\n");
319 _encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t));
320 if( NULL == _encbuf )
321 {
322 printf( "Error: Failed to allocate memory.\n" );
323 if( _key_data )
324 free( _key_data );
325 free( _bin_data );
326 return EXIT_FAILURE;
327 }
328 printf( "\n" );
329 if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
330 _bin_data, _bin_data_len, _encbuf, &_encbuf_len ) )
331 printf("Error: Encryption failed.\n");
332 printf( "\n**********************\n\n" );
333 }
334 else
335 {
336 if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
337 (const uint8_t *)_text, strlen( _text ), NULL, &_encbuf_len ) )
338 printf("Error: Failed to retrieve required buffer size for encryption.\n");
339 _encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t));
340 if( NULL == _encbuf )
341 {
342 printf( "Error: Failed to allocate memory.\n" );
343 if( _key_data )
344 free( _key_data );
345 return EXIT_FAILURE;
346 }
347 printf( "\n" );
348 if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
349 (const uint8_t *)_text, strlen( _text ), _encbuf, &_encbuf_len ) )
350 printf("Error: Encryption failed.\n");
351 printf( "\n**********************\n\n" );
352 }
353
354 if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
355 _encbuf, _encbuf_len, NULL, &_decbuf_len ) )
356 printf("Error: Failed to retrieve required buffer size for encryption.\n");
357 _decbuf = (uint8_t *) calloc(_decbuf_len, sizeof(uint8_t));
358 if( NULL == _decbuf )
359 {
360 printf( "Error: Failed to allocate memory.\n" );
361 if( _key_data )
362 free( _key_data );
363 if( _bin_data )
364 free( _bin_data );
365 free( _encbuf );
366 return EXIT_FAILURE;
367 }
368 if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
369 _encbuf, _encbuf_len, _decbuf, &_decbuf_len ) )
370 printf("Error: Decryption failed.\n");
371
372 if( OAES_RET_SUCCESS != oaes_free( &ctx ) )
373 printf("Error: Failed to uninitialize OAES.\n");
374
375 oaes_sprintf( NULL, &_buf_len, _encbuf, _encbuf_len );
376 _buf = (char *) calloc(_buf_len, sizeof(char));
377 printf( "\n***** cyphertext *****\n" );
378 if( _buf )
379 {
380 oaes_sprintf( _buf, &_buf_len, _encbuf, _encbuf_len );
381 printf( "%s", _buf );
382 }
383 printf( "\n**********************\n" );
384 free( _buf );
385
386 oaes_sprintf( NULL, &_buf_len, _decbuf, _decbuf_len );
387 _buf = (char *) calloc(_buf_len, sizeof(char));
388 printf( "\n***** plaintext *****\n" );
389 if( _buf )
390 {
391 oaes_sprintf( _buf, &_buf_len, _decbuf, _decbuf_len );
392 printf( "%s", _buf );
393 }
394 printf( "\n**********************\n\n" );
395 free( _buf );
396
397 free( _encbuf );
398 free( _decbuf );
399 if( _key_data )
400 free( _key_data );
401 if( _bin_data )
402 free( _bin_data );
403
404 return (EXIT_SUCCESS);
405}