From 6083fd252d3db4743994583d4885a2b6f60bb7ec Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Sat, 3 Dec 2011 21:45:14 +0000 Subject: [PATCH] - Added a generic entropy accumulator that provides support for adding custom entropy sources and added some generic and platform dependent entropy sources --- ChangeLog | 3 + doxygen/input/doc_rng.h | 9 +- include/polarssl/config.h | 28 +++ include/polarssl/entropy.h | 129 +++++++++++++ include/polarssl/entropy_poll.h | 68 +++++++ include/polarssl/error.h | 1 + library/CMakeLists.txt | 2 + library/Makefile | 22 +-- library/entropy.c | 173 ++++++++++++++++++ library/entropy_poll.c | 135 ++++++++++++++ library/error.c | 11 ++ programs/Makefile | 18 +- programs/random/CMakeLists.txt | 12 +- programs/random/gen_entropy.c | 87 +++++++++ programs/random/gen_random_ctr_drbg.c | 91 +++++++++ .../{gen_random.c => gen_random_havege.c} | 0 scripts/generate_errors.pl | 2 +- 17 files changed, 771 insertions(+), 20 deletions(-) create mode 100644 include/polarssl/entropy.h create mode 100644 include/polarssl/entropy_poll.h create mode 100644 library/entropy.c create mode 100644 library/entropy_poll.c create mode 100644 programs/random/gen_entropy.c create mode 100644 programs/random/gen_random_ctr_drbg.c rename programs/random/{gen_random.c => gen_random_havege.c} (100%) diff --git a/ChangeLog b/ChangeLog index 06c8e3b0d..8817d9f12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ Features * Added cipher_get_cipher_mode() and cipher_get_cipher_operation() introspection functions (Closes ticket #40) * Added CTR_DRBG based on AES-256-CTR (NIST SP 800-90) random generator + * Added a generic entropy accumulator that provides support for adding + custom entropy sources and added some generic and platform dependent + entropy sources Changes * Documentation for AES and Camellia in modes CTR and CFB128 clarified. diff --git a/doxygen/input/doc_rng.h b/doxygen/input/doc_rng.h index 252ee1ec6..40852ee14 100644 --- a/doxygen/input/doc_rng.h +++ b/doxygen/input/doc_rng.h @@ -7,7 +7,14 @@ * @addtogroup rng_module Random number generator (RNG) module * * The Random number generator (RNG) module provides random number - * generation, see \c havege_rand(). It uses the HAVEGE (HArdware Volatile + * generation, see \c ctr_dbrg_random() or \c havege_random(). + * + * The former uses the block-cipher counter-mode based deterministic random + * bit generator (CTR_DBRG) as specified in NIST SP800-90. It needs an external + * source of entropy. For these purposes \c entropy_func() can be used. This is + * an implementation based on a simple entropy accumulator design. + * + * The latter random number generator uses the HAVEGE (HArdware Volatile * Entropy Gathering and Expansion) software heuristic which is claimed * to be an unpredictable or empirically strong* random number generation. * diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 27f520b25..1327c431f 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -154,6 +154,17 @@ */ #define POLARSSL_FS_IO +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. +#define POLARSSL_NO_PLATFORM_ENTROPY + */ + /** * \def POLARSSL_PKCS1_V21 * @@ -208,6 +219,7 @@ * Module: library/aes.c * Caller: library/ssl_tls.c * library/pem.c + * library/ctr_drbg.c * * This module enables the following ciphersuites: * SSL_RSA_AES_128_SHA @@ -314,6 +326,8 @@ * Module: library/ctr_drbg.c * Caller: * + * Requires: POLARSSL_AES_C + * * This module provides the CTR_DRBG AES-256 random number generator. */ #define POLARSSL_CTR_DRBG_C @@ -362,6 +376,20 @@ */ #define POLARSSL_DHM_C +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA4_C + * + * This module provides a generic entropy pool + */ +#define POLARSSL_ENTROPY_C + /** * \def POLARSSL_ERROR_C * diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h new file mode 100644 index 000000000..46df9293f --- /dev/null +++ b/include/polarssl/entropy.h @@ -0,0 +1,129 @@ +/** + * \file entropy.h + * + * \brief Entropy accumulator implementation + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ENTROPY_H +#define POLARSSL_ENTROPY_H + +#include + +#include "sha4.h" + +#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003A /**< Critical entropy source failure. */ +#define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003C /**< No more sources can be added. */ + +#define ENTROPY_MIN_POOL 128 /**< Minimum amount of pool entropy needed for release */ +#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +#define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ + +#define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Entropy poll callback pointer + * + * \param data Callback-specific data pointer + * \param output Data to fill + * \param len Maximum size to provide + * \param olen The actual amount of bytes put into the buffer (Can be 0) + * + * \return 0 if no critical failures occurred, + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED otherwise + */ +typedef int (*f_source_ptr)(void *, unsigned char *, size_t, size_t *); + +/** + * \brief Entropy context structure + */ +typedef struct +{ + sha4_context accumulator; + size_t size; + int source_count; + f_source_ptr f_source[ENTROPY_MAX_SOURCES]; + void * p_source[ENTROPY_MAX_SOURCES]; +} +entropy_context; + +/** + * \brief Initialize the context + * + * \param ctx Entropy context to initialize + */ +void entropy_init( entropy_context *ctx ); + +/** + * \brief Adds an entropy source to poll + * + * \param ctx Entropy context + * \param f_source Entropy function + * \param p_source Function data + * + * \return 0 is successful or POLARSSL_ERR_ENTROPY_MAX_SOURCES + */ +int entropy_add_source( entropy_context *ctx, + f_source_ptr f_source, void *p_source ); + +/** + * \brief Trigger an extra gather poll for the accumulator + * + * \param ctx Entropy context + * + * \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_gather( entropy_context *ctx ); + +/** + * \brief Retrieve entropy from the accumulator (Max ENTROPY_BLOCK_SIZE) + * + * \param data Entropy context + * \param output Buffer to fill + * \param len Length of buffer + * + * \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_func( void *data, unsigned char *output, size_t len ); + +/** + * \brief Add data to the accumulator manually + * + * \param ctx Entropy context + * \param data Data to add + * \param len Length of data + * + * \return 0 if successful + */ +int entropy_update_manual( entropy_context *ctx, + const unsigned char *data, size_t len ); + +#ifdef __cplusplus +} +#endif + +#endif /* entropy.h */ diff --git a/include/polarssl/entropy_poll.h b/include/polarssl/entropy_poll.h new file mode 100644 index 000000000..d9acbe5a5 --- /dev/null +++ b/include/polarssl/entropy_poll.h @@ -0,0 +1,68 @@ +/** + * \file entropy_poll.h + * + * \brief Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ENTROPY_POLL_H +#define POLARSSL_ENTROPY_POLL_H + +#include + +#include "config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) +/** + * \brief Platform-specific entropy poll callback + */ +int platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#if defined(POLARSSL_HAVEGE_C) +/** + * \brief HAVEGE based entropy poll callback + * + * Requires an HAVEGE state as its data pointer. + */ +int havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#if defined(POLARSSL_TIMING_C) +/** + * \brief hardclock-based entropy poll callback + */ +int hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* entropy_poll.h */ diff --git a/include/polarssl/error.h b/include/polarssl/error.h index 7ef8a7432..69e7b0488 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -58,6 +58,7 @@ * DES 1 0x0032-0x0032 * NET 11 0x0040-0x0054 * CTR_DBRG 3 0x0034-0x0038 + * ENTROPY 2 0x003A-0x003C * * High-level module nr (3 bits - 0x1...-0x8...) * Name ID Nr of Errors diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 13d9549de..4cfaf33fb 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -14,6 +14,8 @@ set(src debug.c des.c dhm.c + entropy.c + entropy_poll.c error.c havege.c md.c diff --git a/library/Makefile b/library/Makefile index 002087de7..26de4d785 100644 --- a/library/Makefile +++ b/library/Makefile @@ -22,18 +22,18 @@ DLEXT=so # Windows shared library extension: # DLEXT=dll -OBJS= aes.o arc4.o asn1parse.o \ - base64.o bignum.o camellia.o \ +OBJS= aes.o arc4.o asn1parse.o \ + base64.o bignum.o camellia.o \ certs.o cipher.o cipher_wrap.o \ - ctr_drbg.o debug.o \ - des.o dhm.o havege.o \ - error.o \ - md.o md_wrap.o md2.o \ - md4.o md5.o net.o \ - padlock.o pem.o pkcs11.o \ - rsa.o sha1.o sha2.o \ - sha4.o ssl_cli.o ssl_srv.o \ - ssl_tls.o timing.o version.o \ + ctr_drbg.o debug.o des.o \ + dhm.o entropy.o entropy_poll.o \ + error.o havege.o \ + md.o md_wrap.o md2.o \ + md4.o md5.o net.o \ + padlock.o pem.o pkcs11.o \ + rsa.o sha1.o sha2.o \ + sha4.o ssl_cli.o ssl_srv.o \ + ssl_tls.o timing.o version.o \ x509parse.o xtea.o diff --git a/library/entropy.c b/library/entropy.c new file mode 100644 index 000000000..0ece3457a --- /dev/null +++ b/library/entropy.c @@ -0,0 +1,173 @@ +/* + * Entropy accumulator implementation + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_ENTROPY_C) + +#include "polarssl/entropy.h" +#include "polarssl/entropy_poll.h" + +#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ + +void entropy_init( entropy_context *ctx ) +{ + memset( ctx, 0, sizeof(entropy_context) ); + + sha4_starts( &ctx->accumulator, 0 ); + +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) + entropy_add_source( ctx, platform_entropy_poll, NULL ); +#endif +#if defined(POLARSSL_TIMING_C) + entropy_add_source( ctx, hardclock_poll, NULL ); +#endif +} + +int entropy_add_source( entropy_context *ctx, + f_source_ptr f_source, void *p_source ) +{ + if( ctx->source_count >= ENTROPY_MAX_SOURCES ) + return( POLARSSL_ERR_ENTROPY_MAX_SOURCES ); + + ctx->f_source[ctx->source_count] = f_source; + ctx->p_source[ctx->source_count] = p_source; + + ctx->source_count++; + + return( 0 ); +} + +/* + * Entropy accumulator update + */ +int entropy_update( entropy_context *ctx, unsigned char source_id, + const unsigned char *data, size_t len ) +{ + unsigned char header[2]; + unsigned char tmp[ENTROPY_BLOCK_SIZE]; + size_t use_len = len; + const unsigned char *p = data; + + if( use_len > ENTROPY_BLOCK_SIZE ) + { + sha4( data, len, tmp, 0 ); + + p = tmp; + use_len = ENTROPY_BLOCK_SIZE; + } + + header[0] = source_id; + header[1] = use_len & 0xFF; + + sha4_update( &ctx->accumulator, header, 2 ); + sha4_update( &ctx->accumulator, p, use_len ); + + ctx->size += use_len; + + return( 0 ); +} + +int entropy_update_manual( entropy_context *ctx, + const unsigned char *data, size_t len ) +{ + return entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len ); +} + +/* + * Run through the different sources to add entropy to our accumulator + */ +int entropy_gather( entropy_context *ctx ) +{ + int ret, i; + unsigned char buf[ENTROPY_MAX_GATHER]; + size_t olen; + + /* + * Run through our entropy sources + */ + for( i = 0; i < ctx->source_count; i++ ) + { + olen = 0; + if ( ( ret = ctx->f_source[i]( ctx->p_source[i], + buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 ) + { + return( ret ); + } + + /* + * Add if we actually gathered something + */ + if( olen > 0 ) + entropy_update( ctx, (unsigned char) i, buf, olen ); + } + + return( 0 ); +} + +int entropy_func( void *data, unsigned char *output, size_t len ) +{ + int ret, count = 0; + entropy_context *ctx = (entropy_context *) data; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( len > ENTROPY_BLOCK_SIZE ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + + /* + * Always gather extra entropy before a call + */ + do + { + if( count++ > ENTROPY_MAX_LOOP ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + + if( ( ret = entropy_gather( ctx ) ) != 0 ) + return( ret ); + } + while( ctx->size < ENTROPY_MIN_POOL ); + + memset( buf, 0, ENTROPY_BLOCK_SIZE ); + + sha4_finish( &ctx->accumulator, buf ); + + /* + * Perform second SHA-512 on entropy + */ + sha4( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); + + /* + * Reset accumulator + */ + memset( &ctx->accumulator, 0, sizeof( sha4_context ) ); + sha4_starts( &ctx->accumulator, 0 ); + ctx->size = 0; + + memcpy( output, buf, len ); + + return( 0 ); +} + +#endif diff --git a/library/entropy_poll.c b/library/entropy_poll.c new file mode 100644 index 000000000..270eb8692 --- /dev/null +++ b/library/entropy_poll.c @@ -0,0 +1,135 @@ +/* + * Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_ENTROPY_C) + +#include "polarssl/entropy.h" +#include "polarssl/entropy_poll.h" + +#if defined(POLARSSL_TIMING_C) +#include "polarssl/timing.h" +#endif +#if defined(POLARSSL_HAVEGE_C) +#include "polarssl/havege.h" +#endif + +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) +#if defined(_WIN32) + +#include +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include + +int platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + HCRYPTPROV provider; + *olen = 0; + + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) + { + return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + } + + if( CryptGenRandom( provider, len, output ) == FALSE ) + return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + + CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +} +#else + +#include + +int platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + FILE *file; + size_t ret; + ((void) data); + + *olen = 0; + + file = fopen( "/dev/urandom", "rb" ); + if( file == NULL ) + return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + + ret = fread( output, 1, len, file ); + if( ret != len ) + { + fclose( file ); + return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + } + + fclose( file ); + *olen = len; + + return( 0 ); +} +#endif +#endif + +#if defined(POLARSSL_TIMING_C) +int hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned long timer = hardclock(); + ((void) data); + *olen = 0; + + if( len < sizeof(unsigned long) ) + return( 0 ); + + memcpy( output, &timer, sizeof(unsigned long) ); + *olen = sizeof(unsigned long); + + return( 0 ); +} +#endif + +#if defined(POLARSSL_HAVEGE_C) +int havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + havege_state *hs = (havege_state *) data; + *olen = 0; + + if( havege_random( hs, output, len ) != 0 ) + return POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + + *olen = len; + + return( 0 ); +} +#endif + +#endif /* POLARSSL_ENTROPY_C */ diff --git a/library/error.c b/library/error.c index afe8e4573..d5ad61754 100644 --- a/library/error.c +++ b/library/error.c @@ -59,6 +59,10 @@ #include "polarssl/dhm.h" #endif +#if defined(POLARSSL_ENTROPY_C) +#include "polarssl/entropy.h" +#endif + #if defined(POLARSSL_MD_C) #include "polarssl/md.h" #endif @@ -391,6 +395,13 @@ void error_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "DES - The data input has an invalid length" ); #endif /* POLARSSL_DES_C */ +#if defined(POLARSSL_ENTROPY_C) + if( use_ret == -(POLARSSL_ERR_ENTROPY_SOURCE_FAILED) ) + snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_MAX_SOURCES) ) + snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); +#endif /* POLARSSL_ENTROPY_C */ + #if defined(POLARSSL_NET_C) if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) ) snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); diff --git a/programs/Makefile b/programs/Makefile index ceb06229b..c8b6def33 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -19,7 +19,9 @@ APPS = aes/aescrypt2 aes/crypt_and_hash \ pkey/rsa_sign_pss pkey/rsa_verify_pss \ ssl/ssl_client1 ssl/ssl_client2 \ ssl/ssl_server ssl/ssl_fork_server \ - ssl/ssl_mail_client random/gen_random \ + ssl/ssl_mail_client random/gen_entropy \ + random/gen_random_havege \ + random/gen_random_ctr_drbg \ test/ssl_cert_test test/benchmark \ test/selftest test/ssl_test \ x509/cert_app x509/crl_app @@ -104,9 +106,17 @@ pkey/rsa_encrypt: pkey/rsa_encrypt.c ../library/libpolarssl.a echo " CC pkey/rsa_encrypt.c" $(CC) $(CFLAGS) $(OFLAGS) pkey/rsa_encrypt.c $(LDFLAGS) -o $@ -random/gen_random: random/gen_random.c ../library/libpolarssl.a - echo " CC random/gen_random.c" - $(CC) $(CFLAGS) $(OFLAGS) random/gen_random.c $(LDFLAGS) -o $@ +random/gen_entropy: random/gen_entropy.c ../library/libpolarssl.a + echo " CC random/gen_entropy.c" + $(CC) $(CFLAGS) $(OFLAGS) random/gen_entropy.c $(LDFLAGS) -o $@ + +random/gen_random_havege: random/gen_random_havege.c ../library/libpolarssl.a + echo " CC random/gen_random_havege.c" + $(CC) $(CFLAGS) $(OFLAGS) random/gen_random_havege.c $(LDFLAGS) -o $@ + +random/gen_random_ctr_drbg: random/gen_random_ctr_drbg.c ../library/libpolarssl.a + echo " CC random/gen_random_ctr_drbg.c" + $(CC) $(CFLAGS) $(OFLAGS) random/gen_random_ctr_drbg.c $(LDFLAGS) -o $@ ssl/ssl_client1: ssl/ssl_client1.c ../library/libpolarssl.a echo " CC ssl/ssl_client1.c" diff --git a/programs/random/CMakeLists.txt b/programs/random/CMakeLists.txt index 3196e467c..94814c4f2 100644 --- a/programs/random/CMakeLists.txt +++ b/programs/random/CMakeLists.txt @@ -1,6 +1,12 @@ -add_executable(gen_random gen_random.c) -target_link_libraries(gen_random polarssl) +add_executable(gen_random_havege gen_random.c) +target_link_libraries(gen_random_havege polarssl) -INSTALL(TARGETS gen_random +add_executable(gen_random_ctr_drbg gen_random_ctr_drbg.c) +target_link_libraries(gen_random_ctr_drbg polarssl) + +add_executable(gen_entropy gen_entropy.c) +target_link_libraries(gen_entropy polarssl) + +INSTALL(TARGETS gen_random_havege gen_random_ctr_drbg gen_entropy DESTINATION "bin" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c new file mode 100644 index 000000000..38c104c92 --- /dev/null +++ b/programs/random/gen_entropy.c @@ -0,0 +1,87 @@ +/** + * \brief Use and generate multiple entropies calls into a file + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#include "polarssl/entropy.h" + +#include + +#if !defined(POLARSSL_ENTROPY_C) +int main( int argc, char *argv[] ) +{ + ((void) argc); + ((void) argv); + + printf("POLARSSL_ENTROPY_C not defined.\n"); + return( 0 ); +} +#else +int main( int argc, char *argv[] ) +{ + FILE *f; + int i, k, ret; + entropy_context entropy; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( argc < 2 ) + { + fprintf( stderr, "usage: %s \n", argv[0] ); + return( 1 ); + } + + if( ( f = fopen( argv[1], "wb+" ) ) == NULL ) + { + printf( "failed to open '%s' for writing.\n", argv[0] ); + return( 1 ); + } + + entropy_init( &entropy ); + + for( i = 0, k = 768; i < k; i++ ) + { + ret = entropy_func( &entropy, buf, sizeof( buf ) ); + if( ret != 0 ) + { + printf("failed!\n"); + goto cleanup; + } + + fwrite( buf, 1, sizeof( buf ), f ); + + printf( "Generating 32Mb of data in file '%s'... %04.1f" \ + "%% done\r", argv[1], (100 * (float) (i + 1)) / k ); + fflush( stdout ); + } + + ret = 0; + +cleanup: + + fclose( f ); + + return( ret ); +} +#endif /* POLARSSL_ENTROPY_C */ diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c new file mode 100644 index 000000000..e926ad089 --- /dev/null +++ b/programs/random/gen_random_ctr_drbg.c @@ -0,0 +1,91 @@ +/** + * \brief Use and generate random data into a file via the CTR_DBRG based on AES + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#include "polarssl/entropy.h" +#include "polarssl/ctr_drbg.h" + +#include + +#if !defined(POLARSSL_CTR_DRBG_C) || !defined(POLARSSL_ENTROPY_C) +int main( int argc, char *argv[] ) +{ + ((void) argc); + ((void) argv); + + printf("POLARSSL_CTR_DRBG_C or POLARSSL_ENTROPY_C not defined.\n"); + return( 0 ); +} +#else +int main( int argc, char *argv[] ) +{ + FILE *f; + int i, k, ret; + ctr_drbg_context ctr_drbg; + entropy_context entropy; + unsigned char buf[1024]; + + if( argc < 2 ) + { + fprintf( stderr, "usage: %s \n", argv[0] ); + return( 1 ); + } + + if( ( f = fopen( argv[1], "wb+" ) ) == NULL ) + { + printf( "failed to open '%s' for writing.\n", argv[0] ); + return( 1 ); + } + + entropy_init( &entropy ); + ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (unsigned char *) "RANDOM_GEN", 10 ); + ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_OFF ); + + for( i = 0, k = 768; i < k; i++ ) + { + ret = ctr_drbg_random( &ctr_drbg, buf, sizeof( buf ) ); + if( ret != 0 ) + { + printf("failed!\n"); + goto cleanup; + } + + fwrite( buf, 1, sizeof( buf ), f ); + + printf( "Generating 32Mb of data in file '%s'... %04.1f" \ + "%% done\r", argv[1], (100 * (float) (i + 1)) / k ); + fflush( stdout ); + } + + ret = 0; + +cleanup: + + fclose( f ); + + return( ret ); +} +#endif /* POLARSSL_HAVEGE_C && POLARSSL_ENTROPY_C */ diff --git a/programs/random/gen_random.c b/programs/random/gen_random_havege.c similarity index 100% rename from programs/random/gen_random.c rename to programs/random/gen_random_havege.c diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index 6d8b56371..e07200fcc 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -9,7 +9,7 @@ my $error_file = shift or die "Missing destination file"; my $error_format_file = $data_dir.'/error.fmt'; my @low_level_modules = ( "AES", "ASN1", "CAMELLIA", "BIGNUM", "BASE64", "XTEA", - "PADLOCK", "DES", "NET", "CTR_DRBG" ); + "PADLOCK", "DES", "NET", "CTR_DRBG", "ENTROPY" ); my @high_level_modules = ( "PEM", "X509", "DHM", "RSA", "MD", "CIPHER", "SSL" ); my $line_separator = $/;