diff options
Diffstat (limited to 'base/native-tools/src/tkstool/random.c')
-rw-r--r-- | base/native-tools/src/tkstool/random.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/base/native-tools/src/tkstool/random.c b/base/native-tools/src/tkstool/random.c new file mode 100644 index 000000000..49dfb525e --- /dev/null +++ b/base/native-tools/src/tkstool/random.c @@ -0,0 +1,173 @@ +/* --- BEGIN COPYRIGHT BLOCK --- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 Red Hat, Inc. + * All rights reserved. + * --- END COPYRIGHT BLOCK --- + */ + +#include "tkstool.h" + +/* returns 0 for success, -1 for failure (EOF encountered) */ +static int +UpdateRNG( void ) +{ + char *randbuf; + int fd; + int i; + int count; + int c; + int rv = 0; +#ifdef XP_UNIX + cc_t orig_cc_min; + cc_t orig_cc_time; + tcflag_t orig_lflag; + struct termios tio; +#endif + +#define FPS PR_fprintf( PR_STDOUT, + FPS "\n"); + FPS "A random seed must be generated that will be used in the\n"); + FPS "creation of your key. One of the easiest ways to create a\n"); + FPS "random seed is to use the timing of keystrokes on a keyboard.\n"); + FPS "\n"); + FPS "To begin, type keys on the keyboard until this progress meter\n"); + FPS "is full. DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!\n"); + FPS "\n"); + FPS "\n"); + FPS "Continue typing until the progress meter is full:\n\n"); + FPS "| |\r|"); + + /* turn off echo on stdin & return on 1 char instead of NL */ + fd = fileno( stdin ); + +#if defined( XP_UNIX ) && !defined( VMS ) + tcgetattr( fd, &tio ); + orig_lflag = tio.c_lflag; + orig_cc_min = tio.c_cc[VMIN]; + orig_cc_time = tio.c_cc[VTIME]; + tio.c_lflag &= ~ECHO; + tio.c_lflag &= ~ICANON; + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; + tcsetattr( fd, TCSAFLUSH, &tio ); +#endif + + /* Get random noise from keyboard strokes */ + randbuf = ( char * ) PORT_Alloc( RAND_BUF_LENGTH ); + count = 0; + while( randbuf != NULL && count < NUM_KEYSTROKES+1 ) { +#ifdef VMS + c = GENERIC_GETCHAR_NOECHO(); +#elif XP_UNIX + c = getc( stdin ); +#else + c = getch(); +#endif + if( c == EOF ) { + rv = -1; + break; + } + + PK11_RandomUpdate( + /* data */ randbuf, + /* length in bytes */ RAND_BUF_LENGTH ); + + if( c != randbuf[0] ) { + randbuf[0] = c; + + FPS "\r|"); + + for( i = 0 ; + i < count / ( NUM_KEYSTROKES / RAND_BUF_LENGTH ) ; + i++ ) { + FPS "*"); + } + + if( count % ( NUM_KEYSTROKES / RAND_BUF_LENGTH ) == 1 ) { + FPS "/"); + } + + count++; + } + } + + if (randbuf != NULL) free (randbuf); + + FPS "\n\n"); + FPS "Finished.\n"); + + TKS_TypeProceedToContinue(); + + FPS "\n"); + +#undef FPS + +#if defined( XP_UNIX ) && !defined( VMS ) + /* set back termio the way it was */ + tio.c_lflag = orig_lflag; + tio.c_cc[VMIN] = orig_cc_min; + tio.c_cc[VTIME] = orig_cc_time; + tcsetattr( fd, TCSAFLUSH, &tio ); +#endif + + return rv; +} + + +void +TKS_FileForRNG( char *noise ) +{ + char buf[2048]; + PRFileDesc *fd; + PRInt32 count; + + fd = PR_OpenFile( noise, PR_RDONLY, 0666 ); + if( !fd ) { + return; + } + + do { + count = PR_Read( fd, buf, sizeof( buf ) ); + if (count > 0) { + PK11_RandomUpdate( + /* data */ buf, + /* length in bytes */ count ); + } + } while( count > 0 ); + + PR_Close( fd ); +} + + +SECStatus +TKS_SeedRNG( char *noise ) +{ + /* Clear the screen */ + TKS_ClearScreen(); + + /* Seed the RNG */ + if( noise ) { + TKS_FileForRNG( noise ); + } else { + int rv = UpdateRNG(); + if( rv ) { + PORT_SetError( PR_END_OF_FILE_ERROR ); + return SECFailure; + } + } + + return SECSuccess; +} + |