|
/* X * Simple Unix time quantization package X * {mab,lacy}@research.att.com X * v0.5 - 12/95 X * X * TESTED ONLY UNDER SUNOS 4.x and BSDI 2.0. This is unsupported X * software. Use at own risk. Test carefully on new platforms. X */ /* X * The authors of this software are Matt Blaze and Jack Lacy X * Copyright (c) 1995 by AT&T Bell Laboratories. X * X * Permission to use, copy, and modify this software without fee is X * hereby granted, provided that this entire notice is included in all X * copies of any software which is or includes a copy or modification X * of this software and in all copies of the supporting documentation X * for such software. X * X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR X * IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE X * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE X * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR X * PURPOSE. X */ X /* X * WARNING: This package will provide quantized cpu consumption only X * subject to the limitations of the OS on which it is run. It will X * fail in extreme cases (e.g., very very heavy load and very slow X * machines (e.g., .001 MIPS). Understand its limits before you use X * it. X * X * Note that start_quantize takes MILLISECONDS, not microseconds. See X * quantize.3 for details. X * X * To prevent timing attacks (e.g., Kocher) in most PK crypto X * applications in most applications on most cpus, surrounding the X * call to the functions that use the secret with X * start_quantize(100); X * and X * end_quantize(); X * will do reasonably well. X */ X #ifndef NO_QUANTIZE #include <signal.h> #include <setjmp.h> #include <sys/time.h> #include <stdio.h> X static jmp_buf quant_end; static long quant_quantum=0; X static void quant_interrupt() { X long nquantum; X X nquantum = quant_quantum; X if (nquantum != 0) X set_quant_interrupt(nquantum); X else X longjmp(quant_end, 1); X } X static set_quant_interrupt(microsecs) X long microsecs; { X struct itimerval it, oit; X X timerclear(&it.it_interval); X it.it_value.tv_sec = microsecs/1000000; X it.it_value.tv_usec = microsecs%1000000; X (void) signal(SIGVTALRM, quant_interrupt); X return setitimer(ITIMER_VIRTUAL, &it, &oit); } X int start_quantize(quantum) X int quantum; /* millisecs */ { X if (quantum <= 0) X return -1; X quant_quantum = (quantum * 1000) + 1; /* microsecs */ X return set_quant_interrupt(quant_quantum); } X int end_quantize() { X if (setjmp(quant_end)) X return 0; X if (quant_quantum == 0) X return -1; /* start_quantize never called */ X quant_quantum = 0; /* we return at next quantum */ X while (1) X ; X return -1; /* should never happen */ } X #else /* NO_QUANTIZE */ #include <stdio.h> X int start_quantize(quantum) X int quantum; { X fprintf(stderr,"Warning: QUANTIZE not available\n"); X fflush(stderr); X return -1; X } X int end_quantize() { X return -1; } X #endif