mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 11:cada08fc8a70 1 /*
mbedAustin 11:cada08fc8a70 2 * Portable interface to the CPU cycle counter
mbedAustin 11:cada08fc8a70 3 *
mbedAustin 11:cada08fc8a70 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
mbedAustin 11:cada08fc8a70 5 * SPDX-License-Identifier: Apache-2.0
mbedAustin 11:cada08fc8a70 6 *
mbedAustin 11:cada08fc8a70 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
mbedAustin 11:cada08fc8a70 8 * not use this file except in compliance with the License.
mbedAustin 11:cada08fc8a70 9 * You may obtain a copy of the License at
mbedAustin 11:cada08fc8a70 10 *
mbedAustin 11:cada08fc8a70 11 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 11:cada08fc8a70 12 *
mbedAustin 11:cada08fc8a70 13 * Unless required by applicable law or agreed to in writing, software
mbedAustin 11:cada08fc8a70 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
mbedAustin 11:cada08fc8a70 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 11:cada08fc8a70 16 * See the License for the specific language governing permissions and
mbedAustin 11:cada08fc8a70 17 * limitations under the License.
mbedAustin 11:cada08fc8a70 18 *
mbedAustin 11:cada08fc8a70 19 * This file is part of mbed TLS (https://tls.mbed.org)
mbedAustin 11:cada08fc8a70 20 */
mbedAustin 11:cada08fc8a70 21
mbedAustin 11:cada08fc8a70 22 #if !defined(MBEDTLS_CONFIG_FILE)
mbedAustin 11:cada08fc8a70 23 #include "mbedtls/config.h"
mbedAustin 11:cada08fc8a70 24 #else
mbedAustin 11:cada08fc8a70 25 #include MBEDTLS_CONFIG_FILE
mbedAustin 11:cada08fc8a70 26 #endif
mbedAustin 11:cada08fc8a70 27
mbedAustin 11:cada08fc8a70 28 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
mbedAustin 11:cada08fc8a70 29 #include "mbedtls/platform.h"
mbedAustin 11:cada08fc8a70 30 #else
mbedAustin 11:cada08fc8a70 31 #include <stdio.h>
mbedAustin 11:cada08fc8a70 32 #define mbedtls_printf printf
mbedAustin 11:cada08fc8a70 33 #endif
mbedAustin 11:cada08fc8a70 34
mbedAustin 11:cada08fc8a70 35 #if defined(MBEDTLS_TIMING_C)
mbedAustin 11:cada08fc8a70 36
mbedAustin 11:cada08fc8a70 37 #include "mbedtls/timing.h"
mbedAustin 11:cada08fc8a70 38
mbedAustin 11:cada08fc8a70 39 #if !defined(MBEDTLS_TIMING_ALT)
mbedAustin 11:cada08fc8a70 40
mbedAustin 11:cada08fc8a70 41 #ifndef asm
mbedAustin 11:cada08fc8a70 42 #define asm __asm
mbedAustin 11:cada08fc8a70 43 #endif
mbedAustin 11:cada08fc8a70 44
mbedAustin 11:cada08fc8a70 45 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
mbedAustin 11:cada08fc8a70 46
mbedAustin 11:cada08fc8a70 47 #include <windows.h>
mbedAustin 11:cada08fc8a70 48 #include <winbase.h>
mbedAustin 11:cada08fc8a70 49
mbedAustin 11:cada08fc8a70 50 struct _hr_time
mbedAustin 11:cada08fc8a70 51 {
mbedAustin 11:cada08fc8a70 52 LARGE_INTEGER start;
mbedAustin 11:cada08fc8a70 53 };
mbedAustin 11:cada08fc8a70 54
mbedAustin 11:cada08fc8a70 55 #else
mbedAustin 11:cada08fc8a70 56
mbedAustin 11:cada08fc8a70 57 #include <unistd.h>
mbedAustin 11:cada08fc8a70 58 #include <sys/types.h>
mbedAustin 11:cada08fc8a70 59 #include <sys/time.h>
mbedAustin 11:cada08fc8a70 60 #include <signal.h>
mbedAustin 11:cada08fc8a70 61 #include <time.h>
mbedAustin 11:cada08fc8a70 62
mbedAustin 11:cada08fc8a70 63 struct _hr_time
mbedAustin 11:cada08fc8a70 64 {
mbedAustin 11:cada08fc8a70 65 struct timeval start;
mbedAustin 11:cada08fc8a70 66 };
mbedAustin 11:cada08fc8a70 67
mbedAustin 11:cada08fc8a70 68 #endif /* _WIN32 && !EFIX64 && !EFI32 */
mbedAustin 11:cada08fc8a70 69
mbedAustin 11:cada08fc8a70 70 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 71 ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
mbedAustin 11:cada08fc8a70 72
mbedAustin 11:cada08fc8a70 73 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 74
mbedAustin 11:cada08fc8a70 75 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 76 {
mbedAustin 11:cada08fc8a70 77 unsigned long tsc;
mbedAustin 11:cada08fc8a70 78 __asm rdtsc
mbedAustin 11:cada08fc8a70 79 __asm mov [tsc], eax
mbedAustin 11:cada08fc8a70 80 return( tsc );
mbedAustin 11:cada08fc8a70 81 }
mbedAustin 11:cada08fc8a70 82 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 83 ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
mbedAustin 11:cada08fc8a70 84
mbedAustin 11:cada08fc8a70 85 /* some versions of mingw-64 have 32-bit longs even on x84_64 */
mbedAustin 11:cada08fc8a70 86 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 87 defined(__GNUC__) && ( defined(__i386__) || ( \
mbedAustin 11:cada08fc8a70 88 ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
mbedAustin 11:cada08fc8a70 89
mbedAustin 11:cada08fc8a70 90 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 91
mbedAustin 11:cada08fc8a70 92 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 93 {
mbedAustin 11:cada08fc8a70 94 unsigned long lo, hi;
mbedAustin 11:cada08fc8a70 95 asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
mbedAustin 11:cada08fc8a70 96 return( lo );
mbedAustin 11:cada08fc8a70 97 }
mbedAustin 11:cada08fc8a70 98 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 99 __GNUC__ && __i386__ */
mbedAustin 11:cada08fc8a70 100
mbedAustin 11:cada08fc8a70 101 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 102 defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
mbedAustin 11:cada08fc8a70 103
mbedAustin 11:cada08fc8a70 104 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 105
mbedAustin 11:cada08fc8a70 106 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 107 {
mbedAustin 11:cada08fc8a70 108 unsigned long lo, hi;
mbedAustin 11:cada08fc8a70 109 asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
mbedAustin 11:cada08fc8a70 110 return( lo | ( hi << 32 ) );
mbedAustin 11:cada08fc8a70 111 }
mbedAustin 11:cada08fc8a70 112 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 113 __GNUC__ && ( __amd64__ || __x86_64__ ) */
mbedAustin 11:cada08fc8a70 114
mbedAustin 11:cada08fc8a70 115 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 116 defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
mbedAustin 11:cada08fc8a70 117
mbedAustin 11:cada08fc8a70 118 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 119
mbedAustin 11:cada08fc8a70 120 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 121 {
mbedAustin 11:cada08fc8a70 122 unsigned long tbl, tbu0, tbu1;
mbedAustin 11:cada08fc8a70 123
mbedAustin 11:cada08fc8a70 124 do
mbedAustin 11:cada08fc8a70 125 {
mbedAustin 11:cada08fc8a70 126 asm volatile( "mftbu %0" : "=r" (tbu0) );
mbedAustin 11:cada08fc8a70 127 asm volatile( "mftb %0" : "=r" (tbl ) );
mbedAustin 11:cada08fc8a70 128 asm volatile( "mftbu %0" : "=r" (tbu1) );
mbedAustin 11:cada08fc8a70 129 }
mbedAustin 11:cada08fc8a70 130 while( tbu0 != tbu1 );
mbedAustin 11:cada08fc8a70 131
mbedAustin 11:cada08fc8a70 132 return( tbl );
mbedAustin 11:cada08fc8a70 133 }
mbedAustin 11:cada08fc8a70 134 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 135 __GNUC__ && ( __powerpc__ || __ppc__ ) */
mbedAustin 11:cada08fc8a70 136
mbedAustin 11:cada08fc8a70 137 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 138 defined(__GNUC__) && defined(__sparc64__)
mbedAustin 11:cada08fc8a70 139
mbedAustin 11:cada08fc8a70 140 #if defined(__OpenBSD__)
mbedAustin 11:cada08fc8a70 141 #warning OpenBSD does not allow access to tick register using software version instead
mbedAustin 11:cada08fc8a70 142 #else
mbedAustin 11:cada08fc8a70 143 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 144
mbedAustin 11:cada08fc8a70 145 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 146 {
mbedAustin 11:cada08fc8a70 147 unsigned long tick;
mbedAustin 11:cada08fc8a70 148 asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
mbedAustin 11:cada08fc8a70 149 return( tick );
mbedAustin 11:cada08fc8a70 150 }
mbedAustin 11:cada08fc8a70 151 #endif /* __OpenBSD__ */
mbedAustin 11:cada08fc8a70 152 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 153 __GNUC__ && __sparc64__ */
mbedAustin 11:cada08fc8a70 154
mbedAustin 11:cada08fc8a70 155 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 156 defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
mbedAustin 11:cada08fc8a70 157
mbedAustin 11:cada08fc8a70 158 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 159
mbedAustin 11:cada08fc8a70 160 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 161 {
mbedAustin 11:cada08fc8a70 162 unsigned long tick;
mbedAustin 11:cada08fc8a70 163 asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
mbedAustin 11:cada08fc8a70 164 asm volatile( "mov %%g1, %0" : "=r" (tick) );
mbedAustin 11:cada08fc8a70 165 return( tick );
mbedAustin 11:cada08fc8a70 166 }
mbedAustin 11:cada08fc8a70 167 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 168 __GNUC__ && __sparc__ && !__sparc64__ */
mbedAustin 11:cada08fc8a70 169
mbedAustin 11:cada08fc8a70 170 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 171 defined(__GNUC__) && defined(__alpha__)
mbedAustin 11:cada08fc8a70 172
mbedAustin 11:cada08fc8a70 173 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 174
mbedAustin 11:cada08fc8a70 175 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 176 {
mbedAustin 11:cada08fc8a70 177 unsigned long cc;
mbedAustin 11:cada08fc8a70 178 asm volatile( "rpcc %0" : "=r" (cc) );
mbedAustin 11:cada08fc8a70 179 return( cc & 0xFFFFFFFF );
mbedAustin 11:cada08fc8a70 180 }
mbedAustin 11:cada08fc8a70 181 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 182 __GNUC__ && __alpha__ */
mbedAustin 11:cada08fc8a70 183
mbedAustin 11:cada08fc8a70 184 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \
mbedAustin 11:cada08fc8a70 185 defined(__GNUC__) && defined(__ia64__)
mbedAustin 11:cada08fc8a70 186
mbedAustin 11:cada08fc8a70 187 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 188
mbedAustin 11:cada08fc8a70 189 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 190 {
mbedAustin 11:cada08fc8a70 191 unsigned long itc;
mbedAustin 11:cada08fc8a70 192 asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
mbedAustin 11:cada08fc8a70 193 return( itc );
mbedAustin 11:cada08fc8a70 194 }
mbedAustin 11:cada08fc8a70 195 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
mbedAustin 11:cada08fc8a70 196 __GNUC__ && __ia64__ */
mbedAustin 11:cada08fc8a70 197
mbedAustin 11:cada08fc8a70 198 #if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
mbedAustin 11:cada08fc8a70 199 !defined(EFIX64) && !defined(EFI32)
mbedAustin 11:cada08fc8a70 200
mbedAustin 11:cada08fc8a70 201 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 202
mbedAustin 11:cada08fc8a70 203 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 204 {
mbedAustin 11:cada08fc8a70 205 LARGE_INTEGER offset;
mbedAustin 11:cada08fc8a70 206
mbedAustin 11:cada08fc8a70 207 QueryPerformanceCounter( &offset );
mbedAustin 11:cada08fc8a70 208
mbedAustin 11:cada08fc8a70 209 return( (unsigned long)( offset.QuadPart ) );
mbedAustin 11:cada08fc8a70 210 }
mbedAustin 11:cada08fc8a70 211 #endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
mbedAustin 11:cada08fc8a70 212
mbedAustin 11:cada08fc8a70 213 #if !defined(HAVE_HARDCLOCK)
mbedAustin 11:cada08fc8a70 214
mbedAustin 11:cada08fc8a70 215 #define HAVE_HARDCLOCK
mbedAustin 11:cada08fc8a70 216
mbedAustin 11:cada08fc8a70 217 static int hardclock_init = 0;
mbedAustin 11:cada08fc8a70 218 static struct timeval tv_init;
mbedAustin 11:cada08fc8a70 219
mbedAustin 11:cada08fc8a70 220 unsigned long mbedtls_timing_hardclock( void )
mbedAustin 11:cada08fc8a70 221 {
mbedAustin 11:cada08fc8a70 222 struct timeval tv_cur;
mbedAustin 11:cada08fc8a70 223
mbedAustin 11:cada08fc8a70 224 if( hardclock_init == 0 )
mbedAustin 11:cada08fc8a70 225 {
mbedAustin 11:cada08fc8a70 226 gettimeofday( &tv_init, NULL );
mbedAustin 11:cada08fc8a70 227 hardclock_init = 1;
mbedAustin 11:cada08fc8a70 228 }
mbedAustin 11:cada08fc8a70 229
mbedAustin 11:cada08fc8a70 230 gettimeofday( &tv_cur, NULL );
mbedAustin 11:cada08fc8a70 231 return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
mbedAustin 11:cada08fc8a70 232 + ( tv_cur.tv_usec - tv_init.tv_usec ) );
mbedAustin 11:cada08fc8a70 233 }
mbedAustin 11:cada08fc8a70 234 #endif /* !HAVE_HARDCLOCK */
mbedAustin 11:cada08fc8a70 235
mbedAustin 11:cada08fc8a70 236 volatile int mbedtls_timing_alarmed = 0;
mbedAustin 11:cada08fc8a70 237
mbedAustin 11:cada08fc8a70 238 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
mbedAustin 11:cada08fc8a70 239
mbedAustin 11:cada08fc8a70 240 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
mbedAustin 11:cada08fc8a70 241 {
mbedAustin 11:cada08fc8a70 242 unsigned long delta;
mbedAustin 11:cada08fc8a70 243 LARGE_INTEGER offset, hfreq;
mbedAustin 11:cada08fc8a70 244 struct _hr_time *t = (struct _hr_time *) val;
mbedAustin 11:cada08fc8a70 245
mbedAustin 11:cada08fc8a70 246 QueryPerformanceCounter( &offset );
mbedAustin 11:cada08fc8a70 247 QueryPerformanceFrequency( &hfreq );
mbedAustin 11:cada08fc8a70 248
mbedAustin 11:cada08fc8a70 249 delta = (unsigned long)( ( 1000 *
mbedAustin 11:cada08fc8a70 250 ( offset.QuadPart - t->start.QuadPart ) ) /
mbedAustin 11:cada08fc8a70 251 hfreq.QuadPart );
mbedAustin 11:cada08fc8a70 252
mbedAustin 11:cada08fc8a70 253 if( reset )
mbedAustin 11:cada08fc8a70 254 QueryPerformanceCounter( &t->start );
mbedAustin 11:cada08fc8a70 255
mbedAustin 11:cada08fc8a70 256 return( delta );
mbedAustin 11:cada08fc8a70 257 }
mbedAustin 11:cada08fc8a70 258
mbedAustin 11:cada08fc8a70 259 /* It's OK to use a global because alarm() is supposed to be global anyway */
mbedAustin 11:cada08fc8a70 260 static DWORD alarmMs;
mbedAustin 11:cada08fc8a70 261
mbedAustin 11:cada08fc8a70 262 static DWORD WINAPI TimerProc( LPVOID TimerContext )
mbedAustin 11:cada08fc8a70 263 {
mbedAustin 11:cada08fc8a70 264 ((void) TimerContext);
mbedAustin 11:cada08fc8a70 265 Sleep( alarmMs );
mbedAustin 11:cada08fc8a70 266 mbedtls_timing_alarmed = 1;
mbedAustin 11:cada08fc8a70 267 return( TRUE );
mbedAustin 11:cada08fc8a70 268 }
mbedAustin 11:cada08fc8a70 269
mbedAustin 11:cada08fc8a70 270 void mbedtls_set_alarm( int seconds )
mbedAustin 11:cada08fc8a70 271 {
mbedAustin 11:cada08fc8a70 272 DWORD ThreadId;
mbedAustin 11:cada08fc8a70 273
mbedAustin 11:cada08fc8a70 274 mbedtls_timing_alarmed = 0;
mbedAustin 11:cada08fc8a70 275 alarmMs = seconds * 1000;
mbedAustin 11:cada08fc8a70 276 CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) );
mbedAustin 11:cada08fc8a70 277 }
mbedAustin 11:cada08fc8a70 278
mbedAustin 11:cada08fc8a70 279 #else /* _WIN32 && !EFIX64 && !EFI32 */
mbedAustin 11:cada08fc8a70 280
mbedAustin 11:cada08fc8a70 281 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
mbedAustin 11:cada08fc8a70 282 {
mbedAustin 11:cada08fc8a70 283 unsigned long delta;
mbedAustin 11:cada08fc8a70 284 struct timeval offset;
mbedAustin 11:cada08fc8a70 285 struct _hr_time *t = (struct _hr_time *) val;
mbedAustin 11:cada08fc8a70 286
mbedAustin 11:cada08fc8a70 287 gettimeofday( &offset, NULL );
mbedAustin 11:cada08fc8a70 288
mbedAustin 11:cada08fc8a70 289 if( reset )
mbedAustin 11:cada08fc8a70 290 {
mbedAustin 11:cada08fc8a70 291 t->start.tv_sec = offset.tv_sec;
mbedAustin 11:cada08fc8a70 292 t->start.tv_usec = offset.tv_usec;
mbedAustin 11:cada08fc8a70 293 return( 0 );
mbedAustin 11:cada08fc8a70 294 }
mbedAustin 11:cada08fc8a70 295
mbedAustin 11:cada08fc8a70 296 delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
mbedAustin 11:cada08fc8a70 297 + ( offset.tv_usec - t->start.tv_usec ) / 1000;
mbedAustin 11:cada08fc8a70 298
mbedAustin 11:cada08fc8a70 299 return( delta );
mbedAustin 11:cada08fc8a70 300 }
mbedAustin 11:cada08fc8a70 301
mbedAustin 11:cada08fc8a70 302 static void sighandler( int signum )
mbedAustin 11:cada08fc8a70 303 {
mbedAustin 11:cada08fc8a70 304 mbedtls_timing_alarmed = 1;
mbedAustin 11:cada08fc8a70 305 signal( signum, sighandler );
mbedAustin 11:cada08fc8a70 306 }
mbedAustin 11:cada08fc8a70 307
mbedAustin 11:cada08fc8a70 308 void mbedtls_set_alarm( int seconds )
mbedAustin 11:cada08fc8a70 309 {
mbedAustin 11:cada08fc8a70 310 mbedtls_timing_alarmed = 0;
mbedAustin 11:cada08fc8a70 311 signal( SIGALRM, sighandler );
mbedAustin 11:cada08fc8a70 312 alarm( seconds );
mbedAustin 11:cada08fc8a70 313 }
mbedAustin 11:cada08fc8a70 314
mbedAustin 11:cada08fc8a70 315 #endif /* _WIN32 && !EFIX64 && !EFI32 */
mbedAustin 11:cada08fc8a70 316
mbedAustin 11:cada08fc8a70 317 /*
mbedAustin 11:cada08fc8a70 318 * Set delays to watch
mbedAustin 11:cada08fc8a70 319 */
mbedAustin 11:cada08fc8a70 320 void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
mbedAustin 11:cada08fc8a70 321 {
mbedAustin 11:cada08fc8a70 322 mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
mbedAustin 11:cada08fc8a70 323
mbedAustin 11:cada08fc8a70 324 ctx->int_ms = int_ms;
mbedAustin 11:cada08fc8a70 325 ctx->fin_ms = fin_ms;
mbedAustin 11:cada08fc8a70 326
mbedAustin 11:cada08fc8a70 327 if( fin_ms != 0 )
mbedAustin 11:cada08fc8a70 328 (void) mbedtls_timing_get_timer( &ctx->timer, 1 );
mbedAustin 11:cada08fc8a70 329 }
mbedAustin 11:cada08fc8a70 330
mbedAustin 11:cada08fc8a70 331 /*
mbedAustin 11:cada08fc8a70 332 * Get number of delays expired
mbedAustin 11:cada08fc8a70 333 */
mbedAustin 11:cada08fc8a70 334 int mbedtls_timing_get_delay( void *data )
mbedAustin 11:cada08fc8a70 335 {
mbedAustin 11:cada08fc8a70 336 mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
mbedAustin 11:cada08fc8a70 337 unsigned long elapsed_ms;
mbedAustin 11:cada08fc8a70 338
mbedAustin 11:cada08fc8a70 339 if( ctx->fin_ms == 0 )
mbedAustin 11:cada08fc8a70 340 return( -1 );
mbedAustin 11:cada08fc8a70 341
mbedAustin 11:cada08fc8a70 342 elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
mbedAustin 11:cada08fc8a70 343
mbedAustin 11:cada08fc8a70 344 if( elapsed_ms >= ctx->fin_ms )
mbedAustin 11:cada08fc8a70 345 return( 2 );
mbedAustin 11:cada08fc8a70 346
mbedAustin 11:cada08fc8a70 347 if( elapsed_ms >= ctx->int_ms )
mbedAustin 11:cada08fc8a70 348 return( 1 );
mbedAustin 11:cada08fc8a70 349
mbedAustin 11:cada08fc8a70 350 return( 0 );
mbedAustin 11:cada08fc8a70 351 }
mbedAustin 11:cada08fc8a70 352
mbedAustin 11:cada08fc8a70 353 #endif /* !MBEDTLS_TIMING_ALT */
mbedAustin 11:cada08fc8a70 354
mbedAustin 11:cada08fc8a70 355 #if defined(MBEDTLS_SELF_TEST)
mbedAustin 11:cada08fc8a70 356
mbedAustin 11:cada08fc8a70 357 /*
mbedAustin 11:cada08fc8a70 358 * Busy-waits for the given number of milliseconds.
mbedAustin 11:cada08fc8a70 359 * Used for testing mbedtls_timing_hardclock.
mbedAustin 11:cada08fc8a70 360 */
mbedAustin 11:cada08fc8a70 361 static void busy_msleep( unsigned long msec )
mbedAustin 11:cada08fc8a70 362 {
mbedAustin 11:cada08fc8a70 363 struct mbedtls_timing_hr_time hires;
mbedAustin 11:cada08fc8a70 364 unsigned long i = 0; /* for busy-waiting */
mbedAustin 11:cada08fc8a70 365 volatile unsigned long j; /* to prevent optimisation */
mbedAustin 11:cada08fc8a70 366
mbedAustin 11:cada08fc8a70 367 (void) mbedtls_timing_get_timer( &hires, 1 );
mbedAustin 11:cada08fc8a70 368
mbedAustin 11:cada08fc8a70 369 while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
mbedAustin 11:cada08fc8a70 370 i++;
mbedAustin 11:cada08fc8a70 371
mbedAustin 11:cada08fc8a70 372 j = i;
mbedAustin 11:cada08fc8a70 373 (void) j;
mbedAustin 11:cada08fc8a70 374 }
mbedAustin 11:cada08fc8a70 375
mbedAustin 11:cada08fc8a70 376 #define FAIL do \
mbedAustin 11:cada08fc8a70 377 { \
mbedAustin 11:cada08fc8a70 378 if( verbose != 0 ) \
mbedAustin 11:cada08fc8a70 379 mbedtls_printf( "failed\n" ); \
mbedAustin 11:cada08fc8a70 380 \
mbedAustin 11:cada08fc8a70 381 return( 1 ); \
mbedAustin 11:cada08fc8a70 382 } while( 0 )
mbedAustin 11:cada08fc8a70 383
mbedAustin 11:cada08fc8a70 384 /*
mbedAustin 11:cada08fc8a70 385 * Checkup routine
mbedAustin 11:cada08fc8a70 386 *
mbedAustin 11:cada08fc8a70 387 * Warning: this is work in progress, some tests may not be reliable enough
mbedAustin 11:cada08fc8a70 388 * yet! False positives may happen.
mbedAustin 11:cada08fc8a70 389 */
mbedAustin 11:cada08fc8a70 390 int mbedtls_timing_self_test( int verbose )
mbedAustin 11:cada08fc8a70 391 {
mbedAustin 11:cada08fc8a70 392 unsigned long cycles, ratio;
mbedAustin 11:cada08fc8a70 393 unsigned long millisecs, secs;
mbedAustin 11:cada08fc8a70 394 int hardfail;
mbedAustin 11:cada08fc8a70 395 struct mbedtls_timing_hr_time hires;
mbedAustin 11:cada08fc8a70 396 uint32_t a, b;
mbedAustin 11:cada08fc8a70 397 mbedtls_timing_delay_context ctx;
mbedAustin 11:cada08fc8a70 398
mbedAustin 11:cada08fc8a70 399 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 400 mbedtls_printf( " TIMING tests note: will take some time!\n" );
mbedAustin 11:cada08fc8a70 401
mbedAustin 11:cada08fc8a70 402
mbedAustin 11:cada08fc8a70 403 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 404 mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " );
mbedAustin 11:cada08fc8a70 405
mbedAustin 11:cada08fc8a70 406 for( secs = 1; secs <= 3; secs++ )
mbedAustin 11:cada08fc8a70 407 {
mbedAustin 11:cada08fc8a70 408 (void) mbedtls_timing_get_timer( &hires, 1 );
mbedAustin 11:cada08fc8a70 409
mbedAustin 11:cada08fc8a70 410 mbedtls_set_alarm( (int) secs );
mbedAustin 11:cada08fc8a70 411 while( !mbedtls_timing_alarmed )
mbedAustin 11:cada08fc8a70 412 ;
mbedAustin 11:cada08fc8a70 413
mbedAustin 11:cada08fc8a70 414 millisecs = mbedtls_timing_get_timer( &hires, 0 );
mbedAustin 11:cada08fc8a70 415
mbedAustin 11:cada08fc8a70 416 /* For some reason on Windows it looks like alarm has an extra delay
mbedAustin 11:cada08fc8a70 417 * (maybe related to creating a new thread). Allow some room here. */
mbedAustin 11:cada08fc8a70 418 if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
mbedAustin 11:cada08fc8a70 419 {
mbedAustin 11:cada08fc8a70 420 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 421 mbedtls_printf( "failed\n" );
mbedAustin 11:cada08fc8a70 422
mbedAustin 11:cada08fc8a70 423 return( 1 );
mbedAustin 11:cada08fc8a70 424 }
mbedAustin 11:cada08fc8a70 425 }
mbedAustin 11:cada08fc8a70 426
mbedAustin 11:cada08fc8a70 427 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 428 mbedtls_printf( "passed\n" );
mbedAustin 11:cada08fc8a70 429
mbedAustin 11:cada08fc8a70 430 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 431 mbedtls_printf( " TIMING test #2 (set/get_delay ): " );
mbedAustin 11:cada08fc8a70 432
mbedAustin 11:cada08fc8a70 433 for( a = 200; a <= 400; a += 200 )
mbedAustin 11:cada08fc8a70 434 {
mbedAustin 11:cada08fc8a70 435 for( b = 200; b <= 400; b += 200 )
mbedAustin 11:cada08fc8a70 436 {
mbedAustin 11:cada08fc8a70 437 mbedtls_timing_set_delay( &ctx, a, a + b );
mbedAustin 11:cada08fc8a70 438
mbedAustin 11:cada08fc8a70 439 busy_msleep( a - a / 8 );
mbedAustin 11:cada08fc8a70 440 if( mbedtls_timing_get_delay( &ctx ) != 0 )
mbedAustin 11:cada08fc8a70 441 FAIL;
mbedAustin 11:cada08fc8a70 442
mbedAustin 11:cada08fc8a70 443 busy_msleep( a / 4 );
mbedAustin 11:cada08fc8a70 444 if( mbedtls_timing_get_delay( &ctx ) != 1 )
mbedAustin 11:cada08fc8a70 445 FAIL;
mbedAustin 11:cada08fc8a70 446
mbedAustin 11:cada08fc8a70 447 busy_msleep( b - a / 8 - b / 8 );
mbedAustin 11:cada08fc8a70 448 if( mbedtls_timing_get_delay( &ctx ) != 1 )
mbedAustin 11:cada08fc8a70 449 FAIL;
mbedAustin 11:cada08fc8a70 450
mbedAustin 11:cada08fc8a70 451 busy_msleep( b / 4 );
mbedAustin 11:cada08fc8a70 452 if( mbedtls_timing_get_delay( &ctx ) != 2 )
mbedAustin 11:cada08fc8a70 453 FAIL;
mbedAustin 11:cada08fc8a70 454 }
mbedAustin 11:cada08fc8a70 455 }
mbedAustin 11:cada08fc8a70 456
mbedAustin 11:cada08fc8a70 457 mbedtls_timing_set_delay( &ctx, 0, 0 );
mbedAustin 11:cada08fc8a70 458 busy_msleep( 200 );
mbedAustin 11:cada08fc8a70 459 if( mbedtls_timing_get_delay( &ctx ) != -1 )
mbedAustin 11:cada08fc8a70 460 FAIL;
mbedAustin 11:cada08fc8a70 461
mbedAustin 11:cada08fc8a70 462 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 463 mbedtls_printf( "passed\n" );
mbedAustin 11:cada08fc8a70 464
mbedAustin 11:cada08fc8a70 465 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 466 mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " );
mbedAustin 11:cada08fc8a70 467
mbedAustin 11:cada08fc8a70 468 /*
mbedAustin 11:cada08fc8a70 469 * Allow one failure for possible counter wrapping.
mbedAustin 11:cada08fc8a70 470 * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
mbedAustin 11:cada08fc8a70 471 * since the whole test is about 10ms, it shouldn't happen twice in a row.
mbedAustin 11:cada08fc8a70 472 */
mbedAustin 11:cada08fc8a70 473 hardfail = 0;
mbedAustin 11:cada08fc8a70 474
mbedAustin 11:cada08fc8a70 475 hard_test:
mbedAustin 11:cada08fc8a70 476 if( hardfail > 1 )
mbedAustin 11:cada08fc8a70 477 {
mbedAustin 11:cada08fc8a70 478 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 479 mbedtls_printf( "failed (ignored)\n" );
mbedAustin 11:cada08fc8a70 480
mbedAustin 11:cada08fc8a70 481 goto hard_test_done;
mbedAustin 11:cada08fc8a70 482 }
mbedAustin 11:cada08fc8a70 483
mbedAustin 11:cada08fc8a70 484 /* Get a reference ratio cycles/ms */
mbedAustin 11:cada08fc8a70 485 millisecs = 1;
mbedAustin 11:cada08fc8a70 486 cycles = mbedtls_timing_hardclock();
mbedAustin 11:cada08fc8a70 487 busy_msleep( millisecs );
mbedAustin 11:cada08fc8a70 488 cycles = mbedtls_timing_hardclock() - cycles;
mbedAustin 11:cada08fc8a70 489 ratio = cycles / millisecs;
mbedAustin 11:cada08fc8a70 490
mbedAustin 11:cada08fc8a70 491 /* Check that the ratio is mostly constant */
mbedAustin 11:cada08fc8a70 492 for( millisecs = 2; millisecs <= 4; millisecs++ )
mbedAustin 11:cada08fc8a70 493 {
mbedAustin 11:cada08fc8a70 494 cycles = mbedtls_timing_hardclock();
mbedAustin 11:cada08fc8a70 495 busy_msleep( millisecs );
mbedAustin 11:cada08fc8a70 496 cycles = mbedtls_timing_hardclock() - cycles;
mbedAustin 11:cada08fc8a70 497
mbedAustin 11:cada08fc8a70 498 /* Allow variation up to 20% */
mbedAustin 11:cada08fc8a70 499 if( cycles / millisecs < ratio - ratio / 5 ||
mbedAustin 11:cada08fc8a70 500 cycles / millisecs > ratio + ratio / 5 )
mbedAustin 11:cada08fc8a70 501 {
mbedAustin 11:cada08fc8a70 502 hardfail++;
mbedAustin 11:cada08fc8a70 503 goto hard_test;
mbedAustin 11:cada08fc8a70 504 }
mbedAustin 11:cada08fc8a70 505 }
mbedAustin 11:cada08fc8a70 506
mbedAustin 11:cada08fc8a70 507 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 508 mbedtls_printf( "passed\n" );
mbedAustin 11:cada08fc8a70 509
mbedAustin 11:cada08fc8a70 510 hard_test_done:
mbedAustin 11:cada08fc8a70 511
mbedAustin 11:cada08fc8a70 512 if( verbose != 0 )
mbedAustin 11:cada08fc8a70 513 mbedtls_printf( "\n" );
mbedAustin 11:cada08fc8a70 514
mbedAustin 11:cada08fc8a70 515 return( 0 );
mbedAustin 11:cada08fc8a70 516 }
mbedAustin 11:cada08fc8a70 517
mbedAustin 11:cada08fc8a70 518 #endif /* MBEDTLS_SELF_TEST */
mbedAustin 11:cada08fc8a70 519
mbedAustin 11:cada08fc8a70 520 #endif /* MBEDTLS_TIMING_C */