This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
maclobdell
Date:
Wed May 18 19:06:32 2016 +0000
Revision:
0:f7c60d3e7b8a
clean version

Who changed what in which revision?

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