Hannes Tschofenig
/
aes-gcm-test-program
Example program to test AES-GCM functionality. Used for a workshop
Embed:
(wiki syntax)
Show/hide line numbers
timing.c
00001 /* 00002 * Portable interface to the CPU cycle counter 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #if !defined(POLARSSL_CONFIG_FILE) 00027 #include "polarssl/config.h" 00028 #else 00029 #include POLARSSL_CONFIG_FILE 00030 #endif 00031 00032 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_PLATFORM_C) 00033 #include "polarssl/platform.h" 00034 #else 00035 #include <stdio.h> 00036 #define polarssl_printf printf 00037 #endif 00038 00039 #if defined(POLARSSL_TIMING_C) && !defined(POLARSSL_TIMING_ALT) 00040 00041 #include "polarssl/timing.h" 00042 00043 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00044 00045 #include <windows.h> 00046 #include <winbase.h> 00047 00048 struct _hr_time 00049 { 00050 LARGE_INTEGER start; 00051 }; 00052 00053 #else 00054 00055 #include <unistd.h> 00056 #include <sys/types.h> 00057 #include <sys/time.h> 00058 #include <signal.h> 00059 #include <time.h> 00060 00061 struct _hr_time 00062 { 00063 struct timeval start; 00064 }; 00065 00066 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00067 00068 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00069 (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 00070 00071 #define POLARSSL_HAVE_HARDCLOCK 00072 00073 unsigned long hardclock( void ) 00074 { 00075 unsigned long tsc; 00076 __asm rdtsc 00077 __asm mov [tsc], eax 00078 return( tsc ); 00079 } 00080 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00081 ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ 00082 00083 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00084 defined(__GNUC__) && defined(__i386__) 00085 00086 #define POLARSSL_HAVE_HARDCLOCK 00087 00088 unsigned long hardclock( void ) 00089 { 00090 unsigned long lo, hi; 00091 asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); 00092 return( lo ); 00093 } 00094 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00095 __GNUC__ && __i386__ */ 00096 00097 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00098 defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) 00099 00100 #define POLARSSL_HAVE_HARDCLOCK 00101 00102 unsigned long hardclock( void ) 00103 { 00104 unsigned long lo, hi; 00105 asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); 00106 return( lo | (hi << 32) ); 00107 } 00108 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00109 __GNUC__ && ( __amd64__ || __x86_64__ ) */ 00110 00111 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00112 defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) 00113 00114 #define POLARSSL_HAVE_HARDCLOCK 00115 00116 unsigned long hardclock( void ) 00117 { 00118 unsigned long tbl, tbu0, tbu1; 00119 00120 do 00121 { 00122 asm volatile( "mftbu %0" : "=r" (tbu0) ); 00123 asm volatile( "mftb %0" : "=r" (tbl ) ); 00124 asm volatile( "mftbu %0" : "=r" (tbu1) ); 00125 } 00126 while( tbu0 != tbu1 ); 00127 00128 return( tbl ); 00129 } 00130 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00131 __GNUC__ && ( __powerpc__ || __ppc__ ) */ 00132 00133 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00134 defined(__GNUC__) && defined(__sparc64__) 00135 00136 #if defined(__OpenBSD__) 00137 #warning OpenBSD does not allow access to tick register using software version instead 00138 #else 00139 #define POLARSSL_HAVE_HARDCLOCK 00140 00141 unsigned long hardclock( void ) 00142 { 00143 unsigned long tick; 00144 asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); 00145 return( tick ); 00146 } 00147 #endif /* __OpenBSD__ */ 00148 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00149 __GNUC__ && __sparc64__ */ 00150 00151 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00152 defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) 00153 00154 #define POLARSSL_HAVE_HARDCLOCK 00155 00156 unsigned long hardclock( void ) 00157 { 00158 unsigned long tick; 00159 asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); 00160 asm volatile( "mov %%g1, %0" : "=r" (tick) ); 00161 return( tick ); 00162 } 00163 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00164 __GNUC__ && __sparc__ && !__sparc64__ */ 00165 00166 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00167 defined(__GNUC__) && defined(__alpha__) 00168 00169 #define POLARSSL_HAVE_HARDCLOCK 00170 00171 unsigned long hardclock( void ) 00172 { 00173 unsigned long cc; 00174 asm volatile( "rpcc %0" : "=r" (cc) ); 00175 return( cc & 0xFFFFFFFF ); 00176 } 00177 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00178 __GNUC__ && __alpha__ */ 00179 00180 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ 00181 defined(__GNUC__) && defined(__ia64__) 00182 00183 #define POLARSSL_HAVE_HARDCLOCK 00184 00185 unsigned long hardclock( void ) 00186 { 00187 unsigned long itc; 00188 asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); 00189 return( itc ); 00190 } 00191 #endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && 00192 __GNUC__ && __ia64__ */ 00193 00194 #if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(_MSC_VER) && \ 00195 !defined(EFIX64) && !defined(EFI32) 00196 00197 #define POLARSSL_HAVE_HARDCLOCK 00198 00199 unsigned long hardclock( void ) 00200 { 00201 LARGE_INTEGER offset; 00202 00203 QueryPerformanceCounter( &offset ); 00204 00205 return (unsigned long)( offset.QuadPart ); 00206 } 00207 #endif /* !POLARSSL_HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ 00208 00209 #if !defined(POLARSSL_HAVE_HARDCLOCK) 00210 00211 #define POLARSSL_HAVE_HARDCLOCK 00212 00213 static int hardclock_init = 0; 00214 static struct timeval tv_init; 00215 00216 unsigned long hardclock( void ) 00217 { 00218 struct timeval tv_cur; 00219 00220 if( hardclock_init == 0 ) 00221 { 00222 gettimeofday( &tv_init, NULL ); 00223 hardclock_init = 1; 00224 } 00225 00226 gettimeofday( &tv_cur, NULL ); 00227 return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 00228 + ( tv_cur.tv_usec - tv_init.tv_usec ) ); 00229 } 00230 #endif /* !POLARSSL_HAVE_HARDCLOCK */ 00231 00232 volatile int alarmed = 0; 00233 00234 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00235 00236 unsigned long get_timer( struct hr_time *val, int reset ) 00237 { 00238 unsigned long delta; 00239 LARGE_INTEGER offset, hfreq; 00240 struct _hr_time *t = (struct _hr_time *) val; 00241 00242 QueryPerformanceCounter( &offset ); 00243 QueryPerformanceFrequency( &hfreq ); 00244 00245 delta = (unsigned long)( ( 1000 * 00246 ( offset.QuadPart - t->start.QuadPart ) ) / 00247 hfreq.QuadPart ); 00248 00249 if( reset ) 00250 QueryPerformanceCounter( &t->start ); 00251 00252 return( delta ); 00253 } 00254 00255 DWORD WINAPI TimerProc( LPVOID uElapse ) 00256 { 00257 Sleep( (DWORD) uElapse ); 00258 alarmed = 1; 00259 return( TRUE ); 00260 } 00261 00262 void set_alarm( int seconds ) 00263 { 00264 DWORD ThreadId; 00265 00266 alarmed = 0; 00267 CloseHandle( CreateThread( NULL, 0, TimerProc, 00268 (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) ); 00269 } 00270 00271 void m_sleep( int milliseconds ) 00272 { 00273 Sleep( milliseconds ); 00274 } 00275 00276 #else /* _WIN32 && !EFIX64 && !EFI32 */ 00277 00278 unsigned long get_timer( struct hr_time *val, int reset ) 00279 { 00280 unsigned long delta; 00281 struct timeval offset; 00282 struct _hr_time *t = (struct _hr_time *) val; 00283 00284 gettimeofday( &offset, NULL ); 00285 00286 delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 00287 + ( offset.tv_usec - t->start.tv_usec ) / 1000; 00288 00289 if( reset ) 00290 { 00291 t->start.tv_sec = offset.tv_sec; 00292 t->start.tv_usec = offset.tv_usec; 00293 } 00294 00295 return( delta ); 00296 } 00297 00298 #if defined(INTEGRITY) 00299 void m_sleep( int milliseconds ) 00300 { 00301 usleep( milliseconds * 1000 ); 00302 } 00303 00304 #else /* INTEGRITY */ 00305 00306 static void sighandler( int signum ) 00307 { 00308 alarmed = 1; 00309 signal( signum, sighandler ); 00310 } 00311 00312 void set_alarm( int seconds ) 00313 { 00314 alarmed = 0; 00315 signal( SIGALRM, sighandler ); 00316 alarm( seconds ); 00317 } 00318 00319 void m_sleep( int milliseconds ) 00320 { 00321 struct timeval tv; 00322 00323 tv.tv_sec = milliseconds / 1000; 00324 tv.tv_usec = ( milliseconds % 1000 ) * 1000; 00325 00326 select( 0, NULL, NULL, NULL, &tv ); 00327 } 00328 #endif /* INTEGRITY */ 00329 00330 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00331 00332 #if defined(POLARSSL_SELF_TEST) 00333 00334 /* To test net_usleep against our functions */ 00335 #if defined(POLARSSL_NET_C) 00336 #include "polarssl/net.h" 00337 #endif 00338 00339 /* 00340 * Checkup routine 00341 * 00342 * Warning: this is work in progress, some tests may not be reliable enough 00343 * yet! False positives may happen. 00344 */ 00345 int timing_self_test( int verbose ) 00346 { 00347 unsigned long cycles, ratio; 00348 unsigned long millisecs, secs; 00349 int hardfail; 00350 struct hr_time hires; 00351 00352 if( verbose != 0) 00353 polarssl_printf( " TIMING tests warning: will take some time!\n" ); 00354 00355 if( verbose != 0 ) 00356 polarssl_printf( " TIMING test #1 (m_sleep / get_timer): " ); 00357 00358 for( secs = 1; secs <= 3; secs++ ) 00359 { 00360 (void) get_timer( &hires, 1 ); 00361 00362 m_sleep( 500 * secs ); 00363 00364 millisecs = get_timer( &hires, 0 ); 00365 00366 if( millisecs < 450 * secs || millisecs > 550 * secs ) 00367 { 00368 if( verbose != 0 ) 00369 polarssl_printf( "failed\n" ); 00370 00371 return( 1 ); 00372 } 00373 } 00374 00375 if( verbose != 0 ) 00376 polarssl_printf( "passed\n" ); 00377 00378 if( verbose != 0 ) 00379 polarssl_printf( " TIMING test #2 (set_alarm / get_timer): " ); 00380 00381 for( secs = 1; secs <= 3; secs++ ) 00382 { 00383 (void) get_timer( &hires, 1 ); 00384 00385 set_alarm( secs ); 00386 while( !alarmed ) 00387 ; 00388 00389 millisecs = get_timer( &hires, 0 ); 00390 00391 if( millisecs < 900 * secs || millisecs > 1100 * secs ) 00392 { 00393 if( verbose != 0 ) 00394 polarssl_printf( "failed\n" ); 00395 00396 return( 1 ); 00397 } 00398 } 00399 00400 if( verbose != 0 ) 00401 polarssl_printf( "passed\n" ); 00402 00403 if( verbose != 0 ) 00404 polarssl_printf( " TIMING test #3 (hardclock / m_sleep ): " ); 00405 00406 /* 00407 * Allow one failure for possible counter wrapping. 00408 * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; 00409 * since the whole test is about 10ms, it shouldn't happen twice in a row. 00410 */ 00411 hardfail = 0; 00412 00413 hard_test: 00414 if( hardfail > 1 ) 00415 { 00416 if( verbose != 0 ) 00417 polarssl_printf( "failed\n" ); 00418 00419 return( 1 ); 00420 } 00421 00422 /* Get a reference ratio cycles/ms */ 00423 cycles = hardclock(); 00424 m_sleep( 1 ); 00425 cycles = hardclock() - cycles; 00426 ratio = cycles / 1; 00427 00428 for( millisecs = 2; millisecs <= 4; millisecs++ ) 00429 { 00430 cycles = hardclock(); 00431 m_sleep( millisecs ); 00432 cycles = hardclock() - cycles; 00433 00434 /* Allow variation up to 20% */ 00435 if( cycles / millisecs < ratio - ratio / 5 || 00436 cycles / millisecs > ratio + ratio / 5 ) 00437 { 00438 hardfail++; 00439 goto hard_test; 00440 } 00441 } 00442 00443 if( verbose != 0 ) 00444 polarssl_printf( "passed\n" ); 00445 00446 if( verbose != 0 ) 00447 polarssl_printf( "\n" ); 00448 00449 #if defined(POLARSSL_NET_C) 00450 if( verbose != 0 ) 00451 polarssl_printf( " TIMING test #4 (net_usleep/ get_timer): " ); 00452 00453 for( secs = 1; secs <= 3; secs++ ) 00454 { 00455 (void) get_timer( &hires, 1 ); 00456 00457 net_usleep( 500000 * secs ); 00458 00459 millisecs = get_timer( &hires, 0 ); 00460 00461 if( millisecs < 450 * secs || millisecs > 550 * secs ) 00462 { 00463 if( verbose != 0 ) 00464 polarssl_printf( "failed\n" ); 00465 00466 return( 1 ); 00467 } 00468 } 00469 00470 if( verbose != 0 ) 00471 polarssl_printf( "passed\n" ); 00472 #endif /* POLARSSL_NET_C */ 00473 00474 return( 0 ); 00475 } 00476 00477 #endif /* POLARSSL_SELF_TEST */ 00478 00479 #endif /* POLARSSL_TIMING_C && !POLARSSL_TIMING_ALT */ 00480 00481
Generated on Tue Jul 12 2022 19:40:21 by 1.7.2