Browse Source

some clean up

master
Georg Hopp 14 years ago
parent
commit
3b95766a2d
  1. 4
      Makefile.am
  2. 8
      gentoo/ChangeLog
  3. 5
      gentoo/metadata.xml
  4. 22
      gentoo/mod_entropy-9999.ebuild
  5. 129
      mod_entropy.c
  6. 102
      mod_entropy_add_entropy.c
  7. 77
      mod_entropy_get_entropy_bits.c

4
Makefile.am

@ -2,7 +2,9 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libmodentropy.la lib_LTLIBRARIES = libmodentropy.la
libmodentropy_la_SOURCES = mod_entropy.c
libmodentropy_la_SOURCES = mod_entropy.c \
mod_entropy_get_entropy_bits.c \
mod_entropy_add_entropy.c
libmodentropy_la_LDFLAGS = -lrt -lm libmodentropy_la_LDFLAGS = -lrt -lm
install: libmodentropy.la install: libmodentropy.la

8
gentoo/ChangeLog

@ -0,0 +1,8 @@
# ChangeLog for www-apache/mod_tidy
# Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2
*mod_entropy-0.1.0 (10 May 2012)
10 May 2012; Georg Hopp <georg@steffers.org> +metadata.xml, +mod_entropy-9999.ebuild:
initial version

5
gentoo/metadata.xml

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<herd>apache</herd>
</pkgmetadata>

22
gentoo/mod_entropy-9999.ebuild

@ -0,0 +1,22 @@
EAPI=4
inherit eutils git autotools apache-module
DESCRIPTION="a module to greate random data from incoming requests."
SRC_URI=""
EGIT_REPO_URI="git://redminie.weird-web-workers.org/var/lib/git/mod_entropy"
HOMEPAGE="http://redmine.weird-web-workers.org/mod_entropy/"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE=""
need_apache2
DOCFILES="COPYING README NEWS ChangeLog"
src_prepare() {
eautoreconf
}

129
mod_entropy.c

@ -1,4 +1,6 @@
/** /**
* \file
*
* this filter generates a sha1 from the current microtime and request * this filter generates a sha1 from the current microtime and request
* useses this to fill the linux random source. * useses this to fill the linux random source.
* *
@ -9,8 +11,22 @@
* *
* Most time was spend in figuring out how to write apache modules. * Most time was spend in figuring out how to write apache modules.
* *
* \author Georg Hopp <georg@steffers.org>
* \author Georg Hopp <georg@steffers.org
*
* \copyright
* Copyright © 2012 Georg Hopp
* 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, either version 3 of the License, or
* (at your option) any later version.
* 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, see <http://www.gnu.org/licenses/>.
*/ */
#define _POSIX_C_SOURCE 199309L #define _POSIX_C_SOURCE 199309L
#include "httpd.h" #include "httpd.h"
@ -24,67 +40,16 @@
#include "apr_sha1.h" #include "apr_sha1.h"
#include <time.h> #include <time.h>
#include <math.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/random.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define min(x, y) ((x)<(y)?(x):(y))
int add_entropy(unsigned char *, size_t);
module AP_MODULE_DECLARE_DATA entropy_module; module AP_MODULE_DECLARE_DATA entropy_module;
char * getData(const char *, size_t);
/** /**
* This is taken from timer_entropyd and modified so
* that the constant 1/log(2.0) is not calculated but
* set directly.
*
* As far as i can say this correlates to the shannon
* entropy algorithm with equal probabilities
* for entropy where the entropy units are bits.
*
* But actually i am no mathemacian and my analysis capabilities
* are limited. Additionally i have not analysed the linux random
* character device code, so i trusted the code in timer_entropyd.
* add header values to sha1
*/ */
static
int
get_entropy(const unsigned char * data, size_t ndata)
{
size_t byte_count[256];
size_t iterator;
static double log2inv = 1.442695; //!< 1 / log(2.0): the entropy unit size
double entropy = 0.0;
memset(byte_count, 0, sizeof(byte_count));
/**
* first get the amount each byte occurs in the array
*/
for (iterator = 0; iterator < ndata; iterator++) {
byte_count[data[iterator]]++;
}
for (iterator = 0; iterator < 256; iterator++) {
double probability = (double)byte_count[iterator] / (double)ndata;
if (0.0 < probability) {
entropy += probability * log2inv * (log(1.0 / probability));
}
}
entropy *= (double)ndata;
entropy = (entropy < 0.0)? 0.0 : entropy;
entropy = min((double)(ndata * 8), entropy);
return entropy;
}
static static
int int
header_do_print(void * rec, const char * key, const char * value) header_do_print(void * rec, const char * key, const char * value)
@ -183,59 +148,11 @@ entropy_filter_in(
/** /**
* fill /dev/random with sha1 from current request * fill /dev/random with sha1 from current request
*/ */
{
int i;
int entropy = get_entropy(digest, APR_SHA1_DIGESTSIZE);
int fd = open("/dev/random", O_WRONLY|O_NONBLOCK);
struct rand_pool_info * output;
output = (struct rand_pool_info *)malloc(
sizeof(struct rand_pool_info) + APR_SHA1_DIGESTSIZE);
output->entropy_count = entropy;
output->buf_size = APR_SHA1_DIGESTSIZE;
memcpy(output->buf, digest, APR_SHA1_DIGESTSIZE);
fprintf(stderr, "sha1 so far: ");
for (i=0; i<APR_SHA1_DIGESTSIZE; i++) {
fprintf(stderr, "%02x", digest[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, "entropy bits: %d\n", entropy);
if (ioctl(fd, RNDADDENTROPY, output) == -1) {
switch(errno) {
case EBADF:
fprintf(stderr, "ioctl failed: no valid file descriptor %d\n", fd);
break;
case EFAULT:
fprintf(stderr, "ioctl failed: invalid argument: %p\n", output);
break;
case EINVAL:
fprintf(stderr, "ioctl failed: invalid request\n", errno);
break;
case ENOTTY:
fprintf(stderr, "ioctl failed: discriptor not associated to character device\n", errno);
break;
case EPERM:
fprintf(stderr, "ioctl failed: invalid permissions\n", errno);
break;
default:
fprintf(stderr, "ioctl(RNDADDENTROPY) failed: %d\n", errno);
break;
}
}
free(output);
close(fd);
}
fflush(stderr);
add_entropy(digest, APR_SHA1_DIGESTSIZE);
/**
* after we are done remove us from filter queue
*/
ap_remove_input_filter(filter); ap_remove_input_filter(filter);
return status; return status;

102
mod_entropy_add_entropy.c

@ -0,0 +1,102 @@
/**
* \file
*
* This adds the generated random bytes (sha1 hash of request) to the
* /dev/random
*
* \author Georg Hopp <georg@steffers.org
*
* \copyright
* Copyright © 2012 Georg Hopp
* 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, either version 3 of the License, or
* (at your option) any later version.
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <linux/random.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
int get_entropy_bits(unsigned char *, size_t);
/**
* fill /dev/random with sha1 from current request
*
* \todo add error handling...
*/
void
add_entropy(const unsigned char * data, size_t ndata)
{
int i;
int fd;
int entropy = get_entropy_bits(data, ndata);
struct rand_pool_info * output;
output = (struct rand_pool_info *)malloc(
sizeof(struct rand_pool_info) + ndata);
output->entropy_count = entropy;
output->buf_size = ndata;
memcpy(output->buf, data, ndata);
fd = open("/dev/random", O_WRONLY|O_NONBLOCK);
if (ioctl(fd, RNDADDENTROPY, output) == -1) {
switch(errno) {
case EBADF:
fprintf(stderr,
"ioctl failed: no valid file descriptor %d\n",
fd);
break;
case EFAULT:
fprintf(stderr,
"ioctl failed: invalid argument: %p\n",
output);
break;
case EINVAL:
fprintf(stderr,
"ioctl failed: invalid request\n",
errno);
break;
case ENOTTY:
fprintf(stderr,
"ioctl failed: discriptor not associated to "
"character device\n",
errno);
break;
case EPERM:
fprintf(stderr,
"ioctl failed: invalid permissions\n",
errno);
break;
default:
fprintf(stderr,
"ioctl(RNDADDENTROPY) failed: %d\n",
errno);
break;
}
}
fflush(stderr);
free(output);
close(fd);
}
// vim: set ts=4 sw=4:

77
mod_entropy_get_entropy_bits.c

@ -0,0 +1,77 @@
/**
* \file
*
* calculate the available entropy. This is taken from timed_entropyd.
*
* \author Georg Hopp <georg@steffers.org
*
* \copyright
* Copyright © 2012 Georg Hopp
* 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, either version 3 of the License, or
* (at your option) any later version.
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
#define min(x, y) ((x)<(y)?(x):(y))
/**
* This is taken from timer_entropyd and modified so
* that the constant 1/log(2.0) is not calculated but
* set directly.
*
* As far as i can say this correlates to the shannon
* entropy algorithm with equal probabilities
* for entropy where the entropy units are bits.
*
* But actually i am no mathemacian and my analysis capabilities
* are limited. Additionally i have not analysed the linux random
* character device code, so i trusted the code in timer_entropyd.
*/
int
get_entropy_bits(const unsigned char * data, size_t ndata)
{
size_t byte_count[256];
size_t iterator;
static double log2inv = 1.442695; //!< 1 / log(2.0): the entropy unit size
double entropy = 0.0;
memset(byte_count, 0, sizeof(byte_count));
/**
* first get the amount each byte occurs in the array
*/
for (iterator = 0; iterator < ndata; iterator++) {
byte_count[data[iterator]]++;
}
/**
* calculate the entropy value
*/
for (iterator = 0; iterator < 256; iterator++) {
double probability = (double)byte_count[iterator] / (double)ndata;
if (0.0 < probability) {
entropy += probability * log2inv * (log(1.0 / probability));
}
}
/**
* prepare for use with linux kernel ioctl RNDADDENTROPY
*/
entropy *= (double)ndata;
entropy = (entropy < 0.0)? 0.0 : entropy;
entropy = min((double)(ndata * 8), entropy);
return entropy;
}
// vim: set ts=4 sw=4:
Loading…
Cancel
Save