diff options
author | Simon Josefsson <simon@josefsson.org> | 2004-08-16 19:10:30 +0000 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2004-08-16 19:10:30 +0000 |
commit | f960d38c20612907b89b6f8c52c35f1c81d5e9f7 (patch) | |
tree | 33de0f18c42cf65bd6a6bbcf420103ccdb58acbb | |
parent | 8898bf167f4a15717536ebf00e86e2747bc486bc (diff) | |
download | gnutls-f960d38c20612907b89b6f8c52c35f1c81d5e9f7.tar.gz |
Move randomness calls to generic crypto API.
Implement randomness for libgcrypt and nettle wrappers.
-rw-r--r-- | configure.in | 69 | ||||
-rw-r--r-- | crypto/gc-libgcrypt.c | 33 | ||||
-rw-r--r-- | crypto/gc-nettle.c | 81 | ||||
-rw-r--r-- | crypto/gc.h | 5 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 2 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 2 | ||||
-rw-r--r-- | lib/gnutls_random.c | 30 | ||||
-rw-r--r-- | lib/gnutls_random.h | 6 |
8 files changed, 217 insertions, 11 deletions
diff --git a/configure.in b/configure.in index 81042ca7f7..262e162567 100644 --- a/configure.in +++ b/configure.in @@ -311,6 +311,75 @@ if test "$nettle" != "no" ; then NETTLE_CFLAGS="-I\$(top_srcdir)/nettle" NETTLE_LIBS="\$(top_builddir)/nettle/libnettle.la" AX_CREATE_STDINT_H([nettle/nettle-types.h], [sys/types.h]) + + # Devices with randomness. + # FIXME: Are these the best defaults? + case "${target}" in + *-openbsd*) + NAME_OF_RANDOM_DEVICE="/dev/srandom" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/prandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + + *-netbsd*) + NAME_OF_RANDOM_DEVICE="/dev/srandom" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + + *-solaris* | *-irix* | *-dec-osf* ) + NAME_OF_RANDOM_DEVICE="/dev/random" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random" + NAME_OF_NONCE_DEVICE="/dev/random" + ;; + + *) + NAME_OF_RANDOM_DEVICE="/dev/random" + NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom" + NAME_OF_NONCE_DEVICE="/dev/urandom" + ;; + esac + + AC_MSG_CHECKING([device with (strong) random data...]) + AC_ARG_ENABLE(random-device, + AC_HELP_STRING([--enable-random-device], + [device with (strong) randomness (for Nettle)]), + NAME_OF_RANDOM_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_RANDOM_DEVICE) + + AC_MSG_CHECKING([device with pseudo random data...]) + AC_ARG_ENABLE(pseudo-random-device, + AC_HELP_STRING([--enable-pseudo-random-device], + [device with pseudo randomness (for Nettle)]), + NAME_OF_PSEUDO_RANDOM_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_PSEUDO_RANDOM_DEVICE) + + AC_MSG_CHECKING([device with unpredictable data for nonces...]) + AC_ARG_ENABLE(nonce-device, + AC_HELP_STRING([--enable-nonce-device], + [device with unpredictable nonces (for Nettle)]), + NAME_OF_NONCE_DEVICE=$enableval) + AC_MSG_RESULT($NAME_OF_NONCE_DEVICE) + + AC_CHECK_FILE($NAME_OF_RANDOM_DEVICE,, AC_MSG_ERROR([[ +*** Device for (strong) random data $NAME_OF_RANDOM_DEVICE does not exist +]])) + AC_CHECK_FILE($NAME_OF_PSEUDO_RANDOM_DEVICE,, AC_MSG_ERROR([[ +*** Device for pseudo-random data $NAME_OF_PSEUDO_RANDOM_DEVICE does not exist +]])) + AC_CHECK_FILE($NAME_OF_NONCE_DEVICE,, AC_MSG_ERROR([[ +*** Device for unpredictable nonces $NAME_OF_NONCE_DEVICE does not exist +]])) + + # FIXME: Open+read 42 bytes+close twice and compare data. Should differ. + + AC_DEFINE_UNQUOTED(NAME_OF_RANDOM_DEVICE, "$NAME_OF_RANDOM_DEVICE", + [defined to the name of the (strong) random device]) + AC_DEFINE_UNQUOTED(NAME_OF_PSEUDO_RANDOM_DEVICE, + "$NAME_OF_PSEUDO_RANDOM_DEVICE", + [defined to the name of the pseudo random device]) + AC_DEFINE_UNQUOTED(NAME_OF_NONCE_DEVICE, "$NAME_OF_NONCE_DEVICE", + [defined to the name of the unpredictable nonce device]) else AC_MSG_RESULT(no) fi diff --git a/crypto/gc-libgcrypt.c b/crypto/gc-libgcrypt.c index bd776eaca9..84c4ee7f5f 100644 --- a/crypto/gc-libgcrypt.c +++ b/crypto/gc-libgcrypt.c @@ -22,12 +22,18 @@ /* Note: This file is only built if GC uses Libgcrypt. */ +#if HAVE_CONFIG_H +# include <config.h> +#endif + /* Get prototype. */ #include <gc.h> /* Get libgcrypt API. */ #include <gcrypt.h> +/* Initialization. */ + int gc_init (void) { @@ -53,6 +59,31 @@ gc_done (void) return; } +/* Randomness. */ + +int +gc_nonce (char *data, size_t datalen) +{ + gcry_create_nonce ((unsigned char *) data, datalen); + return GC_OK; +} + +int +gc_pseudo_random (char *data, size_t datalen) +{ + gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM); + return GC_OK; +} + +int +gc_random (char *data, size_t datalen) +{ + gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM); + return GC_OK; +} + +/* Memory allocation. */ + void gc_set_allocators (gc_malloc_t func_malloc, gc_malloc_t secure_malloc, @@ -63,6 +94,8 @@ gc_set_allocators (gc_malloc_t func_malloc, func_realloc, func_free); } +/* Ciphers. */ + int gc_cipher_open (int alg, int mode, gc_cipher * outhandle) { diff --git a/crypto/gc-nettle.c b/crypto/gc-nettle.c index fdaf521cf6..68d05775fa 100644 --- a/crypto/gc-nettle.c +++ b/crypto/gc-nettle.c @@ -22,11 +22,21 @@ /* Note: This file is only built if GC uses Nettle. */ +#if HAVE_CONFIG_H +# include <config.h> +#endif + #include <stdlib.h> /* Get prototype. */ #include <gc.h> +/* For randomize. */ +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + /* XXX GnuTLS still need Libgcrypt. */ #include <gcrypt.h> @@ -57,6 +67,75 @@ gc_done (void) return; } +/* Randomness. */ + +static int +randomize (int level, char *data, size_t datalen) +{ + int fd; + char *device; + size_t len = 0; + int rc; + + switch (level) + { + case 0: + device = NAME_OF_NONCE_DEVICE; + break; + + case 1: + device = NAME_OF_PSEUDO_RANDOM_DEVICE; + break; + + default: + device = NAME_OF_RANDOM_DEVICE; + break; + } + + fd = open (device, O_RDONLY); + if (fd < 0) + return GC_RANDOM_ERROR; + + do + { + ssize_t tmp; + + tmp = read (fd, data, datalen); + + if (tmp < 0) + return GC_RANDOM_ERROR; + + len += tmp; + } + while (len < datalen); + + rc = close (fd); + if (rc < 0) + return GC_RANDOM_ERROR; + + return GC_OK; +} + +int +gc_nonce (char *data, size_t datalen) +{ + return randomize (0, data, datalen); +} + +int +gc_pseudo_random (char *data, size_t datalen) +{ + return randomize (1, data, datalen); +} + +int +gc_random (char *data, size_t datalen) +{ + return randomize (2, data, datalen); +} + +/* Memory allocation. */ + void gc_set_allocators (gc_malloc_t func_malloc, gc_malloc_t secure_malloc, @@ -68,6 +147,8 @@ gc_set_allocators (gc_malloc_t func_malloc, func_realloc, func_free); } +/* Ciphers. */ + #include "nettle-meta.h" #include "aes.h" diff --git a/crypto/gc.h b/crypto/gc.h index 3f912bfc26..ae3469c8f8 100644 --- a/crypto/gc.h +++ b/crypto/gc.h @@ -31,6 +31,7 @@ enum Gc_rc GC_OK = 0, GC_MALLOC_ERROR, GC_INIT_ERROR, + GC_RANDOM_ERROR, GC_INVALID_CIPHER }; typedef enum Gc_rc Gc_rc; @@ -60,6 +61,10 @@ typedef void *gc_cipher; extern int gc_init (void); extern void gc_done (void); +extern int gc_nonce (char *data, size_t datalen); +extern int gc_pseudo_random (char *data, size_t datalen); +extern int gc_random (char *data, size_t datalen); + /* Memory allocation (avoid). */ typedef void *(*gc_malloc_t) (size_t n); typedef int (*gc_secure_check_t) (const void *); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 66da4496f4..6edc98eba6 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2004 Simon Josefsson * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos * Copyright (C) 2004 Free Software Foundation * @@ -228,6 +229,7 @@ static gnutls_error_entry error_algorithms[] = { ERROR_ENTRY("The Message Authentication Code verification failed.", GNUTLS_E_MAC_VERIFY_FAILED, 1), ERROR_ENTRY("Some constraint limits were reached.", GNUTLS_E_CONSTRAINT_ERROR, 1), + ERROR_ENTRY("Failed to acquire random data.", GNUTLS_E_RANDOM_FAILED, 1), {NULL, NULL, 0, 0} }; diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 97f242ae00..c3e1543c8b 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -125,6 +125,8 @@ #define GNUTLS_E_OPENPGP_KEYRING_ERROR -204 #define GNUTLS_E_X509_UNSUPPORTED_OID -205 +#define GNUTLS_E_RANDOM_FAILED -206 + #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250 /* _INT_ internal errors. Not exported */ diff --git a/lib/gnutls_random.c b/lib/gnutls_random.c index d8360e8e66..e53a593fd1 100644 --- a/lib/gnutls_random.c +++ b/lib/gnutls_random.c @@ -1,16 +1,17 @@ /* + * Copyright (C) 2004 Simon Josefsson * Copyright (C) 2001,2003 Nikos Mavroyanopoulos * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * @@ -32,12 +33,25 @@ */ int _gnutls_get_random(opaque * res, int bytes, int level) { - if (level == GNUTLS_WEAK_RANDOM) { - gcry_create_nonce(res, bytes); - return 0; + int err; + + switch (level) + { + case GNUTLS_WEAK_RANDOM: + err = gc_nonce ((char*) res, (size_t) bytes); + break; + + case GNUTLS_STRONG_RANDOM: + err = gc_pseudo_random ((char*) res, (size_t) bytes); + break; + + default: /* GNUTLS_VERY_STRONG_RANDOM */ + err = gc_random ((char*) res, (size_t) bytes); + break; } - gcry_randomize(res, bytes, level); + if (err != GC_OK) + return GNUTLS_E_RANDOM_FAILED; - return 0; + return GNUTLS_E_SUCCESS; } diff --git a/lib/gnutls_random.h b/lib/gnutls_random.h index 2cbde3cbf6..3b304b4930 100644 --- a/lib/gnutls_random.h +++ b/lib/gnutls_random.h @@ -1,7 +1,7 @@ #include "defines.h" -#define GNUTLS_WEAK_RANDOM GCRY_WEAK_RANDOM -#define GNUTLS_STRONG_RANDOM GCRY_STRONG_RANDOM -#define GNUTLS_VERY_STRONG_RANDOM GCRY_VERY_STRONG_RANDOM +#define GNUTLS_WEAK_RANDOM 0 +#define GNUTLS_STRONG_RANDOM 1 +#define GNUTLS_VERY_STRONG_RANDOM 2 int _gnutls_get_random(opaque * res, int bytes, int); |