⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rnd_keys.c

📁 samba最新软件
💻 C
字号:
/* * Copyright (c) 1995, 1996, 1997, 1999 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. *  * 3. Neither the name of the Institute nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifdef HAVE_CONFIG_H#include "config.h"RCSID("$Id: rnd_keys.c 17445 2006-05-05 10:37:46Z lha $");#endif#ifdef KRB5#include <krb5-types.h>#endif#include <des.h>#include <stdlib.h>#include <string.h>#ifdef TIME_WITH_SYS_TIME#include <sys/time.h>#include <time.h>#elif defined(HAVE_SYS_TIME_H)#include <sys/time.h>#else#include <time.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_IO_H#include <io.h>#endif#ifdef HAVE_SIGNAL_H#include <signal.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif/* * Generate "random" data by checksumming a file. * * Returns -1 if there were any problems with permissions or I/O * errors. */staticintsumFile (const char *name, int len, void *res){  uint32_t sum[2] = { 0, 0 };  uint32_t buf[1024*2];  int fd, i;  fd = open (name, 0);  if (fd < 0)    return -1;  while (len > 0)    {      int n = read(fd, buf, sizeof(buf));      if (n < 0)	{	  close(fd);	  return n;	}      for (i = 0; i < (n/sizeof(buf[0])); i++)	{	  sum[0] += buf[i];	  i++;	  sum[1] += buf[i];	}      len -= n;    }  close (fd);  memcpy (res, &sum, sizeof(sum));  return 0;}#if 0staticintmd5sumFile (const char *name, int len, int32_t sum[4]){  int32_t buf[1024*2];  int fd, cnt;  struct md5 md5;  fd = open (name, 0);  if (fd < 0)    return -1;  md5_init(&md5);  while (len > 0)    {      int n = read(fd, buf, sizeof(buf));      if (n < 0)	{	  close(fd);	  return n;	}      md5_update(&md5, buf, n);      len -= n;    }  md5_finito(&md5, (unsigned char *)sum);  close (fd);  return 0;}#endif/* * Create a sequence of random 64 bit blocks. * The sequence is indexed with a long long and  * based on an initial des key used as a seed. */static DES_key_schedule sequence_seed;static uint32_t sequence_index[2];/*  * Random number generator based on ideas from truerand in cryptolib * as described on page 424 in Applied Cryptography 2 ed. by Bruce * Schneier. */static volatile int counter;static volatile unsigned char *gdata; /* Global data */static volatile int igdata;	/* Index into global data */static int gsize;#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)/* Visual C++ 4.0 (Windows95/NT) */staticRETSIGTYPEsigALRM(int sig){    if (igdata < gsize)	gdata[igdata++] ^= counter & 0xff;#ifndef HAVE_SIGACTION    signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */#endif    SIGRETURN(0);}#endif#if !defined(HAVE_RANDOM) && defined(HAVE_RAND)#ifndef srandom#define srandom srand#endif#ifndef random#define random rand#endif#endif#if !defined(HAVE_SETITIMER) || defined(WIN32) || defined(__EMX__) || defined(__OS2__) || defined(__CYGWIN32__)static voiddes_not_rand_data(unsigned char *data, int size){  int i;  srandom (time (NULL));  for(i = 0; i < size; ++i)    data[i] ^= random() % 0x100;}#endif#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)#ifndef HAVE_SETITIMERstatic voidpacemaker(struct timeval *tv){    fd_set fds;    pid_t pid;    pid = getppid();    while(1){	FD_ZERO(&fds);	FD_SET(0, &fds);	select(1, &fds, NULL, NULL, tv);	kill(pid, SIGALRM);    }}#endif#ifdef HAVE_SIGACTION/* XXX ugly hack, should perhaps use function from roken */static RETSIGTYPE (*fake_signal(int sig, RETSIGTYPE (*f)(int)))(int){    struct sigaction sa, osa;    sa.sa_handler = f;    sa.sa_flags = 0;    sigemptyset(&sa.sa_mask);    sigaction(sig, &sa, &osa);    return osa.sa_handler;}#define signal(S, F) fake_signal((S), (F))#endif/* * Generate size bytes of "random" data using timed interrupts. * It takes about 40ms/byte random data. * It's not neccessary to be root to run it. */voidDES_rand_data(void *outdata, int size){    unsigned char *data = outdata;    struct itimerval tv, otv;    RETSIGTYPE (*osa)(int);    int i, j;#ifndef HAVE_SETITIMER     RETSIGTYPE (*ochld)(int);    pid_t pid;#endif    const char *rnd_devices[] = {"/dev/random",			   "/dev/srandom",			   "/dev/urandom",			   "/dev/arandom",			   NULL};    const char **p;    for(p = rnd_devices; *p; p++) {      int fd = open(*p, O_RDONLY | O_NDELAY);            if(fd >= 0 && read(fd, data, size) == size) {	close(fd);	return;      }      close(fd);    }    /* Paranoia? Initialize data from /dev/mem if we can read it. */    if (size >= 8)      sumFile("/dev/mem", (1024*1024*2), data);    gdata = data;    gsize = size;    igdata = 0;    osa = signal(SIGALRM, sigALRM);      /* Start timer */    tv.it_value.tv_sec = 0;    tv.it_value.tv_usec = 10 * 1000; /* 10 ms */    tv.it_interval = tv.it_value;#ifdef HAVE_SETITIMER    setitimer(ITIMER_REAL, &tv, &otv);#else    ochld = signal(SIGCHLD, SIG_IGN);    pid = fork();    if(pid == -1){	signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);	des_not_rand_data(data, size);	return;    }    if(pid == 0)	pacemaker(&tv.it_interval);#endif    for(i = 0; i < 4; i++) {	for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */	    counter++;	for (j = 0; j < size; j++) /* Only use 2 bits each lap */	    gdata[j] = (gdata[j]>>2) | (gdata[j]<<6);    }#ifdef HAVE_SETITIMER    setitimer(ITIMER_REAL, &otv, 0);#else    kill(pid, SIGKILL);    while(waitpid(pid, NULL, 0) != pid);    signal(SIGCHLD, ochld != SIG_ERR ? ochld : SIG_DFL);#endif    signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL);}#elsevoidDES_rand_data(unsigned char *p, int s){  des_not_rand_data (p, s);}#endifvoidDES_generate_random_block(DES_cblock *block){  DES_rand_data((unsigned char *)block, sizeof(*block));}#define DES_rand_data_key hc_DES_rand_data_keyvoidDES_rand_data_key(DES_cblock *key);/* * Generate a "random" DES key. */voidDES_rand_data_key(DES_cblock *key){    unsigned char data[8];    DES_key_schedule sched;    do {	DES_rand_data(data, sizeof(data));	DES_rand_data((unsigned char*)key, sizeof(DES_cblock));	DES_set_odd_parity(key);	DES_set_key(key, &sched);	DES_ecb_encrypt(&data, key, &sched, DES_ENCRYPT);	memset(&data, 0, sizeof(data));	memset(&sched, 0, sizeof(sched));	DES_set_odd_parity(key);    } while(DES_is_weak_key(key));}/* * Generate "random" data by checksumming /dev/mem * * It's neccessary to be root to run it. Returns -1 if there were any * problems with permissions. */#define DES_mem_rand8 hc_DES_mem_rand8intDES_mem_rand8(unsigned char *data);intDES_mem_rand8(unsigned char *data){  return 1;}/* * In case the generator does not get initialized use this as fallback. */static int initialized;static voiddo_initialize(void){    DES_cblock default_seed;    do {	DES_generate_random_block(&default_seed);	DES_set_odd_parity(&default_seed);    } while (DES_is_weak_key(&default_seed));    DES_init_random_number_generator(&default_seed);}#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0)#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0)#define set_sequence_number(ll) \memcpy((char *)sequence_index, (ll), sizeof(sequence_index));/* * Set the sequnce number to this value (a long long). */voidDES_set_sequence_number(void *ll){    set_sequence_number(ll);}/* * Set the generator seed and reset the sequence number to 0. */voidDES_set_random_generator_seed(DES_cblock *seed){    DES_set_key(seed, &sequence_seed);    zero_long_long(sequence_index);    initialized = 1;}/* * Generate a sequence of random des keys * using the random block sequence, fixup * parity and skip weak keys. */intDES_new_random_key(DES_cblock *key){    if (!initialized)	do_initialize();    do {	DES_ecb_encrypt((DES_cblock *) sequence_index,			key,			&sequence_seed,			DES_ENCRYPT);	incr_long_long(sequence_index);	/* random key must have odd parity and not be weak */	DES_set_odd_parity(key);    } while (DES_is_weak_key(key));    return(0);}/* * des_init_random_number_generator: * * Initialize the sequence of random 64 bit blocks.  The input seed * can be a secret key since it should be well hidden and is also not * kept. * */void DES_init_random_number_generator(DES_cblock *seed){    struct timeval now;    DES_cblock uniq;    DES_cblock new_key;    gettimeofday(&now, (struct timezone *)0);    DES_generate_random_block(&uniq);    /* Pick a unique random key from the shared sequence. */    DES_set_random_generator_seed(seed);    set_sequence_number((unsigned char *)&uniq);    DES_new_random_key(&new_key);    /* Select a new nonshared sequence, */    DES_set_random_generator_seed(&new_key);    /* and use the current time to pick a key for the new sequence. */    set_sequence_number((unsigned char *)&now);    DES_new_random_key(&new_key);    DES_set_random_generator_seed(&new_key);}/* This is for backwards compatibility. */voidDES_random_key(DES_cblock *ret){    DES_new_random_key(ret);}#ifdef TESTRUNintmain(){    unsigned char data[8];    int i;    while (1)        {	    if (sumFile("/dev/mem", (1024*1024*8), data) != 0)	      { perror("sumFile"); exit(1); }            for (i = 0; i < 8; i++)                printf("%02x", data[i]);            printf("\n");        }}#endif#ifdef TESTRUN2intmain(){    DES_cblock data;    int i;    while (1)        {	    do_initialize();            DES_random_key(data);            for (i = 0; i < 8; i++)                printf("%02x", data[i]);            printf("\n");        }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -